aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/DataPluginFactory.cs155
-rw-r--r--OpenSim/Data/GridDataBase.cs52
-rw-r--r--OpenSim/Data/IAvatarData.cs (renamed from OpenSim/Region/Framework/Interfaces/ITeleportModule.cs)20
-rw-r--r--OpenSim/Data/IFriendsData.cs (renamed from OpenSim/Data/ReservationData.cs)27
-rw-r--r--OpenSim/Data/IGridData.cs134
-rw-r--r--OpenSim/Data/IGridUserData.cs (renamed from OpenSim/Grid/Framework/IMessagingServerDiscovery.cs)24
-rw-r--r--OpenSim/Data/ILogData.cs87
-rw-r--r--OpenSim/Data/IPresenceData.cs23
-rw-r--r--OpenSim/Data/IRegionData.cs17
-rw-r--r--OpenSim/Data/IRegionProfileService.cs100
-rw-r--r--OpenSim/Data/IUserAccountData.cs15
-rw-r--r--OpenSim/Data/IUserData.cs209
-rw-r--r--OpenSim/Data/IXInventoryData.cs2
-rw-r--r--OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs219
-rw-r--r--OpenSim/Data/MSSQL/MSSQLAssetData.cs54
-rw-r--r--OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs16
-rw-r--r--OpenSim/Data/MSSQL/MSSQLAvatarData.cs71
-rw-r--r--OpenSim/Data/MSSQL/MSSQLEstateData.cs139
-rw-r--r--OpenSim/Data/MSSQL/MSSQLFriendsData.cs83
-rw-r--r--OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs359
-rw-r--r--OpenSim/Data/MSSQL/MSSQLGridData.cs587
-rw-r--r--OpenSim/Data/MSSQL/MSSQLGridUserData.cs (renamed from OpenSim/Region/Communications/Hypergrid/HGUserDataPlugin.cs)44
-rw-r--r--OpenSim/Data/MSSQL/MSSQLInventoryData.cs206
-rw-r--r--OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs168
-rw-r--r--OpenSim/Data/MSSQL/MSSQLLogData.cs146
-rw-r--r--OpenSim/Data/MSSQL/MSSQLManager.cs221
-rw-r--r--OpenSim/Data/MSSQL/MSSQLPresenceData.cs170
-rw-r--r--OpenSim/Data/MSSQL/MSSQLRegionData.cs40
-rw-r--r--OpenSim/Data/MSSQL/MSSQLUserAccountData.cs306
-rw-r--r--OpenSim/Data/MSSQL/MSSQLUserData.cs1214
-rw-r--r--OpenSim/Data/MSSQL/MSSQLXInventoryData.cs166
-rw-r--r--OpenSim/Data/MSSQL/Resources/001_AuthStore.sql17
-rw-r--r--OpenSim/Data/MSSQL/Resources/001_Avatar.sql15
-rw-r--r--OpenSim/Data/MSSQL/Resources/001_FriendsStore.sql11
-rw-r--r--OpenSim/Data/MSSQL/Resources/001_Presence.sql19
-rw-r--r--OpenSim/Data/MSSQL/Resources/001_UserAccount.sql14
-rw-r--r--OpenSim/Data/MSSQL/Resources/002_AuthStore.sql6
-rw-r--r--OpenSim/Data/MSSQL/Resources/002_FriendsStore.sql6
-rw-r--r--OpenSim/Data/MSSQL/Resources/002_Presence.sql6
-rw-r--r--OpenSim/Data/MSSQL/Resources/002_UserAccount.sql12
-rw-r--r--OpenSim/Data/MSSQL/Resources/003_UserAccount.sql9
-rw-r--r--OpenSim/Data/MSSQL/Resources/004_UserAccount.sql7
-rw-r--r--OpenSim/Data/MSSQL/Resources/007_GridStore.sql9
-rw-r--r--OpenSim/Data/Migration.cs20
-rw-r--r--OpenSim/Data/MySQL/MySQLAssetData.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLAvatarData.cs (renamed from OpenSim/Services/UserService/UserService.cs)53
-rw-r--r--OpenSim/Data/MySQL/MySQLEstateData.cs195
-rw-r--r--OpenSim/Data/MySQL/MySQLFriendsData.cs68
-rw-r--r--OpenSim/Data/MySQL/MySQLGenericTableHandler.cs11
-rw-r--r--OpenSim/Data/MySQL/MySQLGridData.cs422
-rw-r--r--OpenSim/Data/MySQL/MySQLGridUserData.cs (renamed from OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs)46
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs6
-rw-r--r--OpenSim/Data/MySQL/MySQLLogData.cs166
-rw-r--r--OpenSim/Data/MySQL/MySQLManager.cs1248
-rw-r--r--OpenSim/Data/MySQL/MySQLPresenceData.cs155
-rw-r--r--OpenSim/Data/MySQL/MySQLRegionData.cs26
-rw-r--r--OpenSim/Data/MySQL/MySQLSuperManager.cs52
-rw-r--r--OpenSim/Data/MySQL/MySQLUserAccountData.cs150
-rw-r--r--OpenSim/Data/MySQL/MySQLUserData.cs766
-rw-r--r--OpenSim/Data/MySQL/Resources/001_Avatar.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/001_Friends.sql9
-rw-r--r--OpenSim/Data/MySQL/Resources/001_FriendsStore.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/001_Presence.sql15
-rw-r--r--OpenSim/Data/MySQL/Resources/001_UserAccount.sql13
-rw-r--r--OpenSim/Data/MySQL/Resources/002_AuthStore.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/002_Friends.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/002_FriendsStore.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/002_Presence.sql7
-rw-r--r--OpenSim/Data/MySQL/Resources/002_UserAccount.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/003_AuthStore.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/003_Presence.sql6
-rw-r--r--OpenSim/Data/MySQL/Resources/003_UserAccount.sql9
-rw-r--r--OpenSim/Data/MySQL/Resources/004_UserAccount.sql8
-rw-r--r--OpenSim/Data/MySQL/Resources/005_GridStore.sql6
-rw-r--r--OpenSim/Data/MySQL/Resources/006_GridStore.sql5
-rw-r--r--OpenSim/Data/MySQL/Resources/007_GridStore.sql7
-rw-r--r--OpenSim/Data/MySQL/Resources/032_RegionStore.sql3
-rw-r--r--OpenSim/Data/MySQL/Tests/MySQLAssetTest.cs22
-rw-r--r--OpenSim/Data/MySQL/Tests/MySQLEstateTest.cs54
-rw-r--r--OpenSim/Data/MySQL/Tests/MySQLInventoryTest.cs30
-rw-r--r--OpenSim/Data/MySQL/Tests/MySQLRegionTest.cs53
-rw-r--r--OpenSim/Data/MySQL/Tests/MySQLUserTest.cs85
-rw-r--r--OpenSim/Data/Null/NullAuthenticationData.cs (renamed from OpenSim/Grid/UserServer.Modules/GridInfoServiceModule.cs)58
-rw-r--r--OpenSim/Data/Null/NullAvatarData.cs (renamed from OpenSim/Grid/MessagingServer.Modules/PresenceBackreferenceEntry.cs)77
-rw-r--r--OpenSim/Data/Null/NullDataStore.cs6
-rw-r--r--OpenSim/Data/Null/NullFriendsData.cs (renamed from OpenSim/Grid/MessagingServer.Modules/UserDataBaseService.cs)73
-rw-r--r--OpenSim/Data/Null/NullInventoryData.cs193
-rw-r--r--OpenSim/Data/Null/NullPresenceData.cs285
-rw-r--r--OpenSim/Data/Null/NullRegionData.cs63
-rw-r--r--OpenSim/Data/Null/NullUserAccountData.cs160
-rw-r--r--OpenSim/Data/RegionProfileData.cs338
-rw-r--r--OpenSim/Data/RegionProfileServiceProxy.cs119
-rw-r--r--OpenSim/Data/SQLite/Resources/001_AuthStore.sql18
-rw-r--r--OpenSim/Data/SQLite/Resources/001_Avatar.sql9
-rw-r--r--OpenSim/Data/SQLite/Resources/001_FriendsStore.sql10
-rw-r--r--OpenSim/Data/SQLite/Resources/001_UserAccount.sql17
-rw-r--r--OpenSim/Data/SQLite/Resources/002_AuthStore.sql5
-rw-r--r--OpenSim/Data/SQLite/Resources/002_FriendsStore.sql5
-rw-r--r--OpenSim/Data/SQLite/Resources/002_UserAccount.sql5
-rw-r--r--OpenSim/Data/SQLite/SQLiteAssetData.cs5
-rw-r--r--OpenSim/Data/SQLite/SQLiteAuthenticationData.cs262
-rw-r--r--OpenSim/Data/SQLite/SQLiteAvatarData.cs74
-rw-r--r--OpenSim/Data/SQLite/SQLiteEstateData.cs91
-rw-r--r--OpenSim/Data/SQLite/SQLiteFramework.cs36
-rw-r--r--OpenSim/Data/SQLite/SQLiteFriendsData.cs70
-rw-r--r--OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs33
-rw-r--r--OpenSim/Data/SQLite/SQLiteGridData.cs286
-rw-r--r--OpenSim/Data/SQLite/SQLiteInventoryStore.cs63
-rw-r--r--OpenSim/Data/SQLite/SQLiteManager.cs225
-rw-r--r--OpenSim/Data/SQLite/SQLiteRegionData.cs6
-rw-r--r--OpenSim/Data/SQLite/SQLiteUserAccountData.cs81
-rw-r--r--OpenSim/Data/SQLite/SQLiteUserData.cs1262
-rw-r--r--OpenSim/Data/SQLite/SQLiteXInventoryData.cs6
-rw-r--r--OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs64
-rw-r--r--OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs (renamed from OpenSim/Region/Communications/Local/Properties/AssemblyInfo.cs)6
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql12
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql18
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql9
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql10
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql32
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql144
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql17
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql39
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql10
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql8
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql10
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql1
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql6
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql7
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql36
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql38
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql6
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql102
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql20
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql8
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql7
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql6
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql8
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql11
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql37
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql28
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql6
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql8
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql6
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql5
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql8
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql79
-rw-r--r--OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml20
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteAssetData.cs343
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs257
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs74
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteEstateData.cs387
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteFramework.cs95
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs70
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs270
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs909
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteRegionData.cs2321
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs81
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteUtils.cs307
-rw-r--r--OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs155
-rw-r--r--OpenSim/Data/Tests/BasicAssetTest.cs9
-rw-r--r--OpenSim/Data/Tests/BasicEstateTest.cs24
-rw-r--r--OpenSim/Data/Tests/BasicGridTest.cs173
-rw-r--r--OpenSim/Data/Tests/BasicUserTest.cs703
-rw-r--r--OpenSim/Data/Tests/PropertyCompareConstraint.cs12
-rw-r--r--OpenSim/Data/Tests/PropertyScrambler.cs4
-rw-r--r--OpenSim/Data/UserDataBase.cs91
-rw-r--r--OpenSim/Server/Handlers/Simulation/Utils.cs (renamed from OpenSim/Data/MySQL/Tests/MySQLGridTest.cs)97
179 files changed, 10019 insertions, 10149 deletions
diff --git a/OpenSim/Data/DataPluginFactory.cs b/OpenSim/Data/DataPluginFactory.cs
deleted file mode 100644
index 841f71e..0000000
--- a/OpenSim/Data/DataPluginFactory.cs
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenSim.Framework;
31
32namespace OpenSim.Data
33{
34 /// <summary>
35 /// A static class containing methods for obtaining handles to database
36 /// storage objects.
37 /// </summary>
38 public static class DataPluginFactory
39 {
40 /// <summary>
41 /// Based on <typeparam name="T" />, returns the appropriate
42 /// PluginInitialiserBase instance in <paramref name="init" /> and
43 /// extension point path in <paramref name="path" />.
44 /// </summary>
45 /// <param name="connect">
46 /// The DB connection string used when creating a new
47 /// PluginInitialiserBase, returned in <paramref name="init" />.
48 /// </param>
49 /// <param name="init">
50 /// A reference to a PluginInitialiserBase object in which the proper
51 /// initialiser will be returned.
52 /// </param>
53 /// <param name="path">
54 /// A string in which the proper extension point path will be returned.
55 /// </param>
56 /// <typeparam name="T">
57 /// The type of data plugin requested.
58 /// </typeparam>
59 /// <exception cref="NotImplementedException">
60 /// Thrown if <typeparamref name="T" /> is not one of the expected data
61 /// interfaces.
62 /// </exception>
63 private static void PluginLoaderParamFactory<T>(string connect, out PluginInitialiserBase init, out string path) where T : IPlugin
64 {
65 Type type = typeof(T);
66
67 if (type == typeof(IInventoryDataPlugin))
68 {
69 init = new InventoryDataInitialiser(connect);
70 path = "/OpenSim/InventoryData";
71 }
72 else if (type == typeof(IUserDataPlugin))
73 {
74 init = new UserDataInitialiser(connect);
75 path = "/OpenSim/UserData";
76 }
77 else if (type == typeof(IGridDataPlugin))
78 {
79 init = new GridDataInitialiser(connect);
80 path = "/OpenSim/GridData";
81 }
82 else if (type == typeof(ILogDataPlugin))
83 {
84 init = new LogDataInitialiser(connect);
85 path = "/OpenSim/LogData";
86 }
87 else if (type == typeof(IAssetDataPlugin))
88 {
89 init = new AssetDataInitialiser(connect);
90 path = "/OpenSim/AssetData";
91 }
92 else
93 {
94 // We don't support this data plugin.
95 throw new NotImplementedException(String.Format("The type '{0}' is not a valid data plugin.", type));
96 }
97 }
98
99 /// <summary>
100 /// Returns a list of new <typeparamref name="T" /> data plugins.
101 /// Plugins will be requested in the order they were added.
102 /// </summary>
103 /// <param name="provider">
104 /// The filename of the inventory server plugin DLL.
105 /// </param>
106 /// <param name="connect">
107 /// The connection string for the storage backend.
108 /// </param>
109 /// <typeparam name="T">
110 /// The type of data plugin requested.
111 /// </typeparam>
112 /// <returns>
113 /// A list of all loaded plugins matching <typeparamref name="T" />.
114 /// </returns>
115 public static List<T> LoadDataPlugins<T>(string provider, string connect) where T : IPlugin
116 {
117 PluginInitialiserBase pluginInitialiser;
118 string extensionPointPath;
119
120 PluginLoaderParamFactory<T>(connect, out pluginInitialiser, out extensionPointPath);
121
122 using (PluginLoader<T> loader = new PluginLoader<T>(pluginInitialiser))
123 {
124 // loader will try to load all providers (MySQL, MSSQL, etc)
125 // unless it is constrainted to the correct "Provider" entry in the addin.xml
126 loader.Add(extensionPointPath, new PluginProviderFilter(provider));
127 loader.Load();
128
129 return loader.Plugins;
130 }
131 }
132
133 /// <summary>
134 /// Returns a new <typeparamref name="T" /> data plugin instance if
135 /// only one was loaded, otherwise returns null (<c>default(T)</c>).
136 /// </summary>
137 /// <param name="provider">
138 /// The filename of the inventory server plugin DLL.
139 /// </param>
140 /// <param name="connect">
141 /// The connection string for the storage backend.
142 /// </param>
143 /// <typeparam name="T">
144 /// The type of data plugin requested.
145 /// </typeparam>
146 /// <returns>
147 /// A list of all loaded plugins matching <typeparamref name="T" />.
148 /// </returns>
149 public static T LoadDataPlugin<T>(string provider, string connect) where T : IPlugin
150 {
151 List<T> plugins = LoadDataPlugins<T>(provider, connect);
152 return (plugins.Count == 1) ? plugins[0] : default(T);
153 }
154 }
155}
diff --git a/OpenSim/Data/GridDataBase.cs b/OpenSim/Data/GridDataBase.cs
deleted file mode 100644
index a03488b..0000000
--- a/OpenSim/Data/GridDataBase.cs
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using OpenMetaverse;
30
31namespace OpenSim.Data
32{
33 public abstract class GridDataBase : IGridDataPlugin
34 {
35 public abstract RegionProfileData GetProfileByHandle(ulong regionHandle);
36 public abstract RegionProfileData GetProfileByUUID(UUID UUID);
37 public abstract RegionProfileData GetProfileByString(string regionName);
38 public abstract RegionProfileData[] GetProfilesInRange(uint Xmin, uint Ymin, uint Xmax, uint Ymax);
39 public abstract List<RegionProfileData> GetRegionsByName(string namePrefix, uint maxNum);
40 public abstract bool AuthenticateSim(UUID UUID, ulong regionHandle, string simrecvkey);
41 public abstract DataResponse StoreProfile(RegionProfileData profile);
42 public abstract ReservationData GetReservationAtPoint(uint x, uint y);
43 public abstract DataResponse DeleteProfile(string uuid);
44
45 public abstract void Initialise();
46 public abstract void Initialise(string connect);
47 public abstract void Dispose();
48
49 public abstract string Name { get; }
50 public abstract string Version { get; }
51 }
52}
diff --git a/OpenSim/Region/Framework/Interfaces/ITeleportModule.cs b/OpenSim/Data/IAvatarData.cs
index 5f9129d..0a18e21 100644
--- a/OpenSim/Region/Framework/Interfaces/ITeleportModule.cs
+++ b/OpenSim/Data/IAvatarData.cs
@@ -27,15 +27,23 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Text;
31using OpenMetaverse; 30using OpenMetaverse;
32using OpenSim.Region.Framework.Scenes; 31using OpenSim.Framework;
33 32
34namespace OpenSim.Region.Framework.Interfaces 33namespace OpenSim.Data
35{ 34{
36 public interface ITeleportModule 35 // This MUST be a ref type!
36 public class AvatarBaseData
37 { 37 {
38 void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, 38 public UUID PrincipalID;
39 Vector3 lookAt, uint teleportFlags); 39 public Dictionary<string, string> Data;
40 }
41
42 public interface IAvatarData
43 {
44 AvatarBaseData[] Get(string field, string val);
45 bool Store(AvatarBaseData data);
46 bool Delete(UUID principalID, string name);
47 bool Delete(string field, string val);
40 } 48 }
41} 49}
diff --git a/OpenSim/Data/ReservationData.cs b/OpenSim/Data/IFriendsData.cs
index 3956fe6..1f1a031 100644
--- a/OpenSim/Data/ReservationData.cs
+++ b/OpenSim/Data/IFriendsData.cs
@@ -26,23 +26,26 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework;
30 32
31namespace OpenSim.Data 33namespace OpenSim.Data
32{ 34{
33 public class ReservationData 35 public class FriendsData
34 { 36 {
35 public UUID userUUID = UUID.Zero; 37 public UUID PrincipalID;
36 public int reservationMinX = 0; 38 public string Friend;
37 public int reservationMinY = 0; 39 public Dictionary<string, string> Data;
38 public int reservationMaxX = 65536; 40 }
39 public int reservationMaxY = 65536;
40
41 public string reservationName = String.Empty;
42 public string reservationCompany = String.Empty;
43 public bool status = true;
44 41
45 public string gridSendKey = String.Empty; 42 /// <summary>
46 public string gridRecvKey = String.Empty; 43 /// An interface for connecting to the friends datastore
44 /// </summary>
45 public interface IFriendsData
46 {
47 bool Store(FriendsData data);
48 bool Delete(UUID ownerID, string friend);
49 FriendsData[] GetFriends(UUID principalID);
47 } 50 }
48} 51}
diff --git a/OpenSim/Data/IGridData.cs b/OpenSim/Data/IGridData.cs
deleted file mode 100644
index 8bd3811..0000000
--- a/OpenSim/Data/IGridData.cs
+++ /dev/null
@@ -1,134 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using OpenMetaverse;
30using OpenSim.Framework;
31
32namespace OpenSim.Data
33{
34 public enum DataResponse
35 {
36 RESPONSE_OK,
37 RESPONSE_AUTHREQUIRED,
38 RESPONSE_INVALIDCREDENTIALS,
39 RESPONSE_ERROR
40 }
41
42 /// <summary>
43 /// A standard grid interface
44 /// </summary>
45 public interface IGridDataPlugin : IPlugin
46 {
47 /// <summary>
48 /// Initialises the interface
49 /// </summary>
50 void Initialise(string connect);
51
52 /// <summary>
53 /// Returns a sim profile from a regionHandle
54 /// </summary>
55 /// <param name="regionHandle">A 64bit Region Handle</param>
56 /// <returns>A simprofile</returns>
57 RegionProfileData GetProfileByHandle(ulong regionHandle);
58
59 /// <summary>
60 /// Returns a sim profile from a UUID
61 /// </summary>
62 /// <param name="UUID">A 128bit UUID</param>
63 /// <returns>A sim profile</returns>
64 RegionProfileData GetProfileByUUID(UUID UUID);
65
66 /// <summary>
67 /// Returns a sim profile from a string match
68 /// </summary>
69 /// <param name="regionName">A string for a partial region name match</param>
70 /// <returns>A sim profile</returns>
71 RegionProfileData GetProfileByString(string regionName);
72
73 /// <summary>
74 /// Returns all profiles within the specified range
75 /// </summary>
76 /// <param name="Xmin">Minimum sim coordinate (X)</param>
77 /// <param name="Ymin">Minimum sim coordinate (Y)</param>
78 /// <param name="Xmax">Maximum sim coordinate (X)</param>
79 /// <param name="Ymin">Maximum sim coordinate (Y)</param>
80 /// <returns>An array containing all the sim profiles in the specified range</returns>
81 RegionProfileData[] GetProfilesInRange(uint Xmin, uint Ymin, uint Xmax, uint Ymax);
82
83 /// <summary>
84 /// Returns up to maxNum profiles of regions that have a name starting with namePrefix
85 /// </summary>
86 /// <param name="name">The name to match against</param>
87 /// <param name="maxNum">Maximum number of profiles to return</param>
88 /// <returns>A list of sim profiles</returns>
89 List<RegionProfileData> GetRegionsByName(string namePrefix, uint maxNum);
90
91 /// <summary>
92 /// Authenticates a sim by use of its recv key.
93 /// WARNING: Insecure
94 /// </summary>
95 /// <param name="UUID">The UUID sent by the sim</param>
96 /// <param name="regionHandle">The regionhandle sent by the sim</param>
97 /// <param name="simrecvkey">The receiving key sent by the sim</param>
98 /// <returns>Whether the sim has been authenticated</returns>
99 bool AuthenticateSim(UUID UUID, ulong regionHandle, string simrecvkey);
100
101 /// <summary>
102 /// Adds or updates a profile in the database
103 /// </summary>
104 /// <param name="profile">The profile to add</param>
105 /// <returns>RESPONSE_OK if successful, error if not.</returns>
106 DataResponse StoreProfile(RegionProfileData profile);
107
108 /// <summary>
109 /// Remove a profile from the database
110 /// </summary>
111 /// <param name="UUID">ID of profile to remove</param>
112 /// <returns></returns>
113 DataResponse DeleteProfile(string UUID);
114
115 /// <summary>
116 /// Function not used????
117 /// </summary>
118 /// <param name="x"></param>
119 /// <param name="y"></param>
120 /// <returns></returns>
121 ReservationData GetReservationAtPoint(uint x, uint y);
122 }
123
124 public class GridDataInitialiser : PluginInitialiserBase
125 {
126 private string connect;
127 public GridDataInitialiser (string s) { connect = s; }
128 public override void Initialise (IPlugin plugin)
129 {
130 IGridDataPlugin p = plugin as IGridDataPlugin;
131 p.Initialise (connect);
132 }
133 }
134}
diff --git a/OpenSim/Grid/Framework/IMessagingServerDiscovery.cs b/OpenSim/Data/IGridUserData.cs
index c996f4f..bd7a435 100644
--- a/OpenSim/Grid/Framework/IMessagingServerDiscovery.cs
+++ b/OpenSim/Data/IGridUserData.cs
@@ -27,14 +27,24 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Framework.Servers; 30using OpenMetaverse;
31using OpenSim.Framework;
31 32
32namespace OpenSim.Grid.Framework 33namespace OpenSim.Data
33{ 34{
34 public interface IMessagingServerDiscovery 35 // This MUST be a ref type!
36 public class GridUserData
35 { 37 {
36 List<MessageServerInfo> GetMessageServersList(); 38 public string UserID;
37 void RegisterMessageServer(MessageServerInfo m); 39 public Dictionary<string, string> Data;
38 void DeRegisterMessageServer(MessageServerInfo m);
39 } 40 }
40} 41
42 /// <summary>
43 /// An interface for connecting to the user grid datastore
44 /// </summary>
45 public interface IGridUserData
46 {
47 GridUserData GetGridUserData(string userID);
48 bool StoreGridUserData(GridUserData data);
49 }
50} \ No newline at end of file
diff --git a/OpenSim/Data/ILogData.cs b/OpenSim/Data/ILogData.cs
deleted file mode 100644
index 97ca1cc..0000000
--- a/OpenSim/Data/ILogData.cs
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Framework;
29
30namespace OpenSim.Data
31{
32 /// <summary>
33 /// The severity of an individual log message
34 /// </summary>
35 public enum LogSeverity : int
36 {
37 /// <summary>
38 /// Critical: systems failure
39 /// </summary>
40 CRITICAL = 1,
41 /// <summary>
42 /// Major: warning prior to systems failure
43 /// </summary>
44 MAJOR = 2,
45 /// <summary>
46 /// Medium: an individual non-critical task failed
47 /// </summary>
48 MEDIUM = 3,
49 /// <summary>
50 /// Low: Informational warning
51 /// </summary>
52 LOW = 4,
53 /// <summary>
54 /// Info: Information
55 /// </summary>
56 INFO = 5,
57 /// <summary>
58 /// Verbose: Debug Information
59 /// </summary>
60 VERBOSE = 6
61 }
62
63 /// <summary>
64 /// An interface to a LogData storage system
65 /// </summary>
66 public interface ILogDataPlugin : IPlugin
67 {
68 void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,
69 string logMessage);
70
71 /// <summary>
72 /// Initialises the interface
73 /// </summary>
74 void Initialise(string connect);
75 }
76
77 public class LogDataInitialiser : PluginInitialiserBase
78 {
79 private string connect;
80 public LogDataInitialiser (string s) { connect = s; }
81 public override void Initialise (IPlugin plugin)
82 {
83 ILogDataPlugin p = plugin as ILogDataPlugin;
84 p.Initialise (connect);
85 }
86 }
87}
diff --git a/OpenSim/Data/IPresenceData.cs b/OpenSim/Data/IPresenceData.cs
index e5a8ebd..71d0e31 100644
--- a/OpenSim/Data/IPresenceData.cs
+++ b/OpenSim/Data/IPresenceData.cs
@@ -32,25 +32,28 @@ using OpenSim.Framework;
32 32
33namespace OpenSim.Data 33namespace OpenSim.Data
34{ 34{
35 public struct PresenceData 35 // This MUST be a ref type!
36 public class PresenceData
36 { 37 {
37 public UUID UUID; 38 public string UserID;
38 public UUID currentRegion; 39 public UUID RegionID;
40 public UUID SessionID;
39 public Dictionary<string, string> Data; 41 public Dictionary<string, string> Data;
40 } 42 }
41 43
42 /// <summary> 44 /// <summary>
43 /// An interface for connecting to the authentication datastore 45 /// An interface for connecting to the presence datastore
44 /// </summary> 46 /// </summary>
45 public interface IPresenceData 47 public interface IPresenceData
46 { 48 {
47 bool Store(PresenceData data); 49 bool Store(PresenceData data);
48 50
49 PresenceData Get(UUID principalID); 51 PresenceData Get(UUID sessionID);
50 52 void LogoutRegionAgents(UUID regionID);
51 bool SetUserDataItem(UUID principalID, string item, string value); 53 bool ReportAgent(UUID sessionID, UUID regionID, string position, string lookAt);
52 bool SetRegionDataItem(UUID principalID, string item, string value); 54 bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt);
53 55 PresenceData[] Get(string field, string data);
54 bool Delete(UUID regionID); 56 void Prune(string userID);
57 bool Delete(string field, string val);
55 } 58 }
56} 59}
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs
index 7a607ab..8259f9b 100644
--- a/OpenSim/Data/IRegionData.cs
+++ b/OpenSim/Data/IRegionData.cs
@@ -60,5 +60,22 @@ namespace OpenSim.Data
60 60
61 bool Delete(UUID regionID); 61 bool Delete(UUID regionID);
62 62
63 List<RegionData> GetDefaultRegions(UUID scopeID);
64 List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
65 }
66
67 [Flags]
68 public enum RegionFlags : int
69 {
70 DefaultRegion = 1, // Used for new Rez. Random if multiple defined
71 FallbackRegion = 2, // Regions we redirect to when the destination is down
72 RegionOnline = 4, // Set when a region comes online, unset when it unregisters and DeleteOnUnregister is false
73 NoDirectLogin = 8, // Region unavailable for direct logins (by name)
74 Persistent = 16, // Don't remove on unregister
75 LockedOut = 32, // Don't allow registration
76 NoMove = 64, // Don't allow moving this region
77 Reservation = 128, // This is an inactive reservation
78 Authenticate = 256, // Require authentication
79 Hyperlink = 512 // Record represents a HG link
63 } 80 }
64} 81}
diff --git a/OpenSim/Data/IRegionProfileService.cs b/OpenSim/Data/IRegionProfileService.cs
deleted file mode 100644
index b3acc52..0000000
--- a/OpenSim/Data/IRegionProfileService.cs
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenMetaverse;
32
33namespace OpenSim.Data
34{
35 public interface IRegionProfileService
36 {
37 /// <summary>
38 /// Returns a region by argument
39 /// </summary>
40 /// <param name="uuid">A UUID key of the region to return</param>
41 /// <returns>A SimProfileData for the region</returns>
42 RegionProfileData GetRegion(UUID uuid);
43
44 /// <summary>
45 /// Returns a region by argument
46 /// </summary>
47 /// <param name="uuid">A regionHandle of the region to return</param>
48 /// <returns>A SimProfileData for the region</returns>
49 RegionProfileData GetRegion(ulong handle);
50
51 /// <summary>
52 /// Returns a region by argument
53 /// </summary>
54 /// <param name="regionName">A partial regionName of the region to return</param>
55 /// <returns>A SimProfileData for the region</returns>
56 RegionProfileData GetRegion(string regionName);
57
58 List<RegionProfileData> GetRegions(uint xmin, uint ymin, uint xmax, uint ymax);
59 List<RegionProfileData> GetRegions(string name, int maxNum);
60 DataResponse AddUpdateRegion(RegionProfileData sim, RegionProfileData existingSim);
61 DataResponse DeleteRegion(string uuid);
62 }
63
64 public interface IRegionProfileRouter
65 {
66 /// <summary>
67 /// Request sim profile information from a grid server, by Region UUID
68 /// </summary>
69 /// <param name="regionId">The region UUID to look for</param>
70 /// <param name="gridserverUrl"></param>
71 /// <param name="gridserverSendkey"></param>
72 /// <param name="gridserverRecvkey"></param>
73 /// <returns>The sim profile. Null if there was a request failure</returns>
74 /// <remarks>This method should be statics</remarks>
75 RegionProfileData RequestSimProfileData(UUID regionId, Uri gridserverUrl,
76 string gridserverSendkey, string gridserverRecvkey);
77
78 /// <summary>
79 /// Request sim profile information from a grid server, by Region Handle
80 /// </summary>
81 /// <param name="regionHandle">the region handle to look for</param>
82 /// <param name="gridserverUrl"></param>
83 /// <param name="gridserverSendkey"></param>
84 /// <param name="gridserverRecvkey"></param>
85 /// <returns>The sim profile. Null if there was a request failure</returns>
86 RegionProfileData RequestSimProfileData(ulong regionHandle, Uri gridserverUrl,
87 string gridserverSendkey, string gridserverRecvkey);
88
89 /// <summary>
90 /// Request sim profile information from a grid server, by Region Name
91 /// </summary>
92 /// <param name="regionName">the region name to look for</param>
93 /// <param name="gridserverUrl"></param>
94 /// <param name="gridserverSendkey"></param>
95 /// <param name="gridserverRecvkey"></param>
96 /// <returns>The sim profile. Null if there was a request failure</returns>
97 RegionProfileData RequestSimProfileData(string regionName, Uri gridserverUrl,
98 string gridserverSendkey, string gridserverRecvkey);
99 }
100}
diff --git a/OpenSim/Data/IUserAccountData.cs b/OpenSim/Data/IUserAccountData.cs
index 6bec188..906ba6c 100644
--- a/OpenSim/Data/IUserAccountData.cs
+++ b/OpenSim/Data/IUserAccountData.cs
@@ -36,20 +36,19 @@ namespace OpenSim.Data
36 { 36 {
37 public UUID PrincipalID; 37 public UUID PrincipalID;
38 public UUID ScopeID; 38 public UUID ScopeID;
39 public Dictionary<string, object> Data; 39 public string FirstName;
40 public string LastName;
41 public Dictionary<string, string> Data;
40 } 42 }
41 43
42 /// <summary> 44 /// <summary>
43 /// An interface for connecting to the authentication datastore 45 /// An interface for connecting to the user accounts datastore
44 /// </summary> 46 /// </summary>
45 public interface IUserAccountData 47 public interface IUserAccountData
46 { 48 {
47 UserAccountData Get(UUID principalID, UUID ScopeID); 49 UserAccountData[] Get(string[] fields, string[] values);
48
49 List<UserAccountData> Query(UUID principalID, UUID ScopeID, string query);
50
51 bool Store(UserAccountData data); 50 bool Store(UserAccountData data);
52 51 bool Delete(string field, string val);
53 bool SetDataItem(UUID principalID, string item, string value); 52 UserAccountData[] GetUsers(UUID scopeID, string query);
54 } 53 }
55} 54}
diff --git a/OpenSim/Data/IUserData.cs b/OpenSim/Data/IUserData.cs
deleted file mode 100644
index e9a1e81..0000000
--- a/OpenSim/Data/IUserData.cs
+++ /dev/null
@@ -1,209 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenSim.Framework;
32
33namespace OpenSim.Data
34{
35 /// <summary>
36 /// An interface for connecting to user storage servers.
37 /// </summary>
38 public interface IUserDataPlugin : IPlugin
39 {
40 /// <summary>
41 /// Returns a user profile from a database via their UUID
42 /// </summary>
43 /// <param name="user">The user's UUID</param>
44 /// <returns>The user data profile. Returns null if no user is found</returns>
45 UserProfileData GetUserByUUID(UUID user);
46
47 /// <summary>
48 /// Returns a users profile by searching their username parts
49 /// </summary>
50 /// <param name="fname">Account firstname</param>
51 /// <param name="lname">Account lastname</param>
52 /// <returns>The user data profile. Null if no user is found</returns>
53 UserProfileData GetUserByName(string fname, string lname);
54
55 /// <summary>
56 /// Get a user from a given uri.
57 /// </summary>
58 /// <param name="uri"></param>
59 /// <returns>The user data profile. Null if no user is found.</returns>
60 UserProfileData GetUserByUri(Uri uri);
61
62 /// <summary>
63 /// Returns a list of UUIDs firstnames and lastnames that match string query entered into the avatar picker.
64 /// </summary>
65 /// <param name="queryID">ID associated with the user's query. This must match what the client sent</param>
66 /// <param name="query">The filtered contents of the search box when the user hit search.</param>
67 /// <returns>A list of user details. If there are no results than either an empty list or null</returns>
68 List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query);
69
70 /// <summary>
71 /// Returns the current agent for a user searching by it's UUID
72 /// </summary>
73 /// <param name="user">The users UUID</param>
74 /// <returns>The current agent session. Null if no session was found</returns>
75 UserAgentData GetAgentByUUID(UUID user);
76
77 /// <summary>
78 /// Returns the current session agent for a user searching by username
79 /// </summary>
80 /// <param name="name">The users account name</param>
81 /// <returns>The current agent session</returns>
82 UserAgentData GetAgentByName(string name);
83
84 /// <summary>
85 /// Returns the current session agent for a user searching by username parts
86 /// </summary>
87 /// <param name="fname">The users first account name</param>
88 /// <param name="lname">The users account surname</param>
89 /// <returns>The current agent session</returns>
90 UserAgentData GetAgentByName(string fname, string lname);
91
92 /// <summary>
93 /// Stores new web-login key for user during web page login
94 /// </summary>
95 /// <param name="webLoginKey"></param>
96 void StoreWebLoginKey(UUID agentID, UUID webLoginKey);
97
98 /// <summary>
99 /// Adds a new User profile to the database
100 /// </summary>
101 /// <param name="user">UserProfile to add</param>
102 void AddNewUserProfile(UserProfileData user);
103
104 /// <summary>
105 /// Adds a temporary user profile. A temporary userprofile is one that should exist only for the lifetime of
106 /// the process.
107 /// </summary>
108 /// <param name="userProfile"></param>
109 void AddTemporaryUserProfile(UserProfileData userProfile);
110
111 /// <summary>
112 /// Updates an existing user profile
113 /// </summary>
114 /// <param name="user">UserProfile to update</param>
115 bool UpdateUserProfile(UserProfileData user);
116
117 /// <summary>
118 /// Adds a new agent to the database
119 /// </summary>
120 /// <param name="agent">The agent to add</param>
121 void AddNewUserAgent(UserAgentData agent);
122
123 /// <summary>
124 /// Adds a new friend to the database for XUser
125 /// </summary>
126 /// <param name="friendlistowner">The agent that who's friends list is being added to</param>
127 /// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
128 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
129 void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms);
130
131 /// <summary>
132 /// Delete friend on friendlistowner's friendlist.
133 /// </summary>
134 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
135 /// <param name="friend">The Ex-friend agent</param>
136 void RemoveUserFriend(UUID friendlistowner, UUID friend);
137
138 /// <summary>
139 /// Update permissions for friend on friendlistowner's friendlist.
140 /// </summary>
141 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
142 /// <param name="friend">The agent that is getting or loosing permissions</param>
143 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
144 void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms);
145
146 /// <summary>
147 /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for UUID friendslistowner
148 /// </summary>
149 /// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
150 /// <returns>The user's friends. If there are no results than either an empty list or null</returns>
151 List<FriendListItem> GetUserFriendList(UUID friendlistowner);
152
153 /// <summary>
154 /// Returns a list of <see cref="FriendRegionInfo/>s for the specified UUIDs.
155 /// </summary>
156 /// <param name="uuids">
157 /// A <see cref="List"/> of <see cref="UUID/>s to fetch info for
158 /// </param>
159 /// <returns>
160 /// A <see cref="Dictionary"/>, mapping the <see cref="UUID"/>s to <see cref="FriendRegionInfo"/>s.
161 /// </returns>
162 Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos(List<UUID> uuids);
163
164 /// <summary>
165 /// Attempts to move currency units between accounts (NOT RELIABLE / TRUSTWORTHY. DONT TRY RUN YOUR OWN CURRENCY EXCHANGE WITH REAL VALUES)
166 /// </summary>
167 /// <param name="from">The account to transfer from</param>
168 /// <param name="to">The account to transfer to</param>
169 /// <param name="amount">The amount to transfer</param>
170 /// <returns>Successful?</returns>
171 bool MoneyTransferRequest(UUID from, UUID to, uint amount);
172
173 /// <summary>
174 /// Attempts to move inventory between accounts, if inventory is copyable it will be copied into the target account.
175 /// </summary>
176 /// <param name="from">User to transfer from</param>
177 /// <param name="to">User to transfer to</param>
178 /// <param name="inventory">Specified inventory item</param>
179 /// <returns>Successful?</returns>
180 bool InventoryTransferRequest(UUID from, UUID to, UUID inventory);
181
182 /// <summary>
183 /// Initialises the plugin (artificial constructor)
184 /// </summary>
185 void Initialise(string connect);
186
187 /// <summary>
188 /// Gets the user appearance
189 /// </summer>
190 AvatarAppearance GetUserAppearance(UUID user);
191
192 void UpdateUserAppearance(UUID user, AvatarAppearance appearance);
193
194 void ResetAttachments(UUID userID);
195
196 void LogoutUsers(UUID regionID);
197 }
198
199 public class UserDataInitialiser : PluginInitialiserBase
200 {
201 private string connect;
202 public UserDataInitialiser (string s) { connect = s; }
203 public override void Initialise (IPlugin plugin)
204 {
205 IUserDataPlugin p = plugin as IUserDataPlugin;
206 p.Initialise (connect);
207 }
208 }
209}
diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs
index cd9273e..6909136 100644
--- a/OpenSim/Data/IXInventoryData.cs
+++ b/OpenSim/Data/IXInventoryData.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Data
58 public int saleType; 58 public int saleType;
59 public int creationDate; 59 public int creationDate;
60 public UUID groupID; 60 public UUID groupID;
61 public bool groupOwned; 61 public int groupOwned;
62 public int flags; 62 public int flags;
63 public UUID inventoryID; 63 public UUID inventoryID;
64 public UUID avatarID; 64 public UUID avatarID;
diff --git a/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs b/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs
deleted file mode 100644
index 93e48cd..0000000
--- a/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs
+++ /dev/null
@@ -1,219 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Data;
29using System.Data.SqlClient;
30
31namespace OpenSim.Data.MSSQL
32{
33 /// <summary>
34 /// Encapsulates a SqlCommand object but ensures that when it is disposed, its connection is closed and disposed also.
35 /// </summary>
36 internal class AutoClosingSqlCommand : IDbCommand
37 {
38 private SqlCommand realCommand;
39
40 public AutoClosingSqlCommand(SqlCommand cmd)
41 {
42 realCommand = cmd;
43 }
44
45 #region IDbCommand Members
46
47 public void Cancel()
48 {
49 realCommand.Cancel();
50 }
51
52 public string CommandText
53 {
54 get
55 {
56 return realCommand.CommandText;
57 }
58 set
59 {
60 realCommand.CommandText = value;
61 }
62 }
63
64 public int CommandTimeout
65 {
66 get
67 {
68 return realCommand.CommandTimeout;
69 }
70 set
71 {
72 realCommand.CommandTimeout = value;
73 }
74 }
75
76 public CommandType CommandType
77 {
78 get
79 {
80 return realCommand.CommandType;
81 }
82 set
83 {
84 realCommand.CommandType = value;
85 }
86 }
87
88 IDbConnection IDbCommand.Connection
89 {
90 get
91 {
92 return realCommand.Connection;
93 }
94 set
95 {
96 realCommand.Connection = (SqlConnection) value;
97 }
98 }
99
100 public SqlConnection Connection
101 {
102 get
103 {
104 return realCommand.Connection;
105 }
106 }
107
108 IDbDataParameter IDbCommand.CreateParameter()
109 {
110 return realCommand.CreateParameter();
111 }
112
113 public SqlParameter CreateParameter()
114 {
115 return realCommand.CreateParameter();
116 }
117
118 public int ExecuteNonQuery()
119 {
120 return realCommand.ExecuteNonQuery();
121 }
122
123 IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior)
124 {
125 return realCommand.ExecuteReader(behavior);
126 }
127
128 public SqlDataReader ExecuteReader(CommandBehavior behavior)
129 {
130 return realCommand.ExecuteReader(behavior);
131 }
132
133 IDataReader IDbCommand.ExecuteReader()
134 {
135 return realCommand.ExecuteReader();
136 }
137
138 public SqlDataReader ExecuteReader()
139 {
140 return realCommand.ExecuteReader();
141 }
142
143 public object ExecuteScalar()
144 {
145 return realCommand.ExecuteScalar();
146 }
147
148 IDataParameterCollection IDbCommand.Parameters
149 {
150 get { return realCommand.Parameters; }
151 }
152
153 public SqlParameterCollection Parameters
154 {
155 get { return realCommand.Parameters; }
156 }
157
158 public void Prepare()
159 {
160 realCommand.Prepare();
161 }
162
163// IDbTransaction IDbCommand.Transaction
164// {
165// get
166// {
167// return realCommand.Transaction;
168// }
169// set
170// {
171// realCommand.Transaction = (SqlTransaction) value;
172// }
173// }
174
175 public IDbTransaction Transaction
176 {
177 get { return realCommand.Transaction; }
178 set { realCommand.Transaction = (SqlTransaction)value; }
179 }
180
181 UpdateRowSource IDbCommand.UpdatedRowSource
182 {
183 get
184 {
185 return realCommand.UpdatedRowSource;
186 }
187 set
188 {
189 realCommand.UpdatedRowSource = value;
190 }
191 }
192
193 #endregion
194
195 #region IDisposable Members
196
197 public void Dispose()
198 {
199 SqlConnection conn = realCommand.Connection;
200 try
201 {
202 realCommand.Dispose();
203 }
204 finally
205 {
206 try
207 {
208 conn.Close();
209 }
210 finally
211 {
212 conn.Dispose();
213 }
214 }
215 }
216
217 #endregion
218 }
219}
diff --git a/OpenSim/Data/MSSQL/MSSQLAssetData.cs b/OpenSim/Data/MSSQL/MSSQLAssetData.cs
index 1ce4abf..d6ea262 100644
--- a/OpenSim/Data/MSSQL/MSSQLAssetData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLAssetData.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Data.MSSQL
49 /// Database manager 49 /// Database manager
50 /// </summary> 50 /// </summary>
51 private MSSQLManager m_database; 51 private MSSQLManager m_database;
52 private string m_connectionString;
52 53
53 #region IPlugin Members 54 #region IPlugin Members
54 55
@@ -75,23 +76,8 @@ namespace OpenSim.Data.MSSQL
75 { 76 {
76 m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks; 77 m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
77 78
78 if (!string.IsNullOrEmpty(connectionString)) 79 m_database = new MSSQLManager(connectionString);
79 { 80 m_connectionString = connectionString;
80 m_database = new MSSQLManager(connectionString);
81 }
82 else
83 {
84 IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini");
85 string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source");
86 string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog");
87 string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info");
88 string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id");
89 string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password");
90
91 m_database =
92 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
93 settingPassword);
94 }
95 81
96 //New migration to check for DB changes 82 //New migration to check for DB changes
97 m_database.CheckMigration(_migrationStore); 83 m_database.CheckMigration(_migrationStore);
@@ -125,17 +111,20 @@ namespace OpenSim.Data.MSSQL
125 override public AssetBase GetAsset(UUID assetID) 111 override public AssetBase GetAsset(UUID assetID)
126 { 112 {
127 string sql = "SELECT * FROM assets WHERE id = @id"; 113 string sql = "SELECT * FROM assets WHERE id = @id";
128 using (AutoClosingSqlCommand command = m_database.Query(sql)) 114 using (SqlConnection conn = new SqlConnection(m_connectionString))
115 using (SqlCommand cmd = new SqlCommand(sql, conn))
129 { 116 {
130 command.Parameters.Add(m_database.CreateParameter("id", assetID)); 117 cmd.Parameters.Add(m_database.CreateParameter("id", assetID));
131 using (SqlDataReader reader = command.ExecuteReader()) 118 conn.Open();
119 using (SqlDataReader reader = cmd.ExecuteReader())
132 { 120 {
133 if (reader.Read()) 121 if (reader.Read())
134 { 122 {
135 AssetBase asset = new AssetBase( 123 AssetBase asset = new AssetBase(
136 new UUID((Guid)reader["id"]), 124 new UUID((Guid)reader["id"]),
137 (string)reader["name"], 125 (string)reader["name"],
138 Convert.ToSByte(reader["assetType"]) 126 Convert.ToSByte(reader["assetType"]),
127 String.Empty
139 ); 128 );
140 // Region Main 129 // Region Main
141 asset.Description = (string)reader["description"]; 130 asset.Description = (string)reader["description"];
@@ -190,7 +179,8 @@ namespace OpenSim.Data.MSSQL
190 m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add"); 179 m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
191 } 180 }
192 181
193 using (AutoClosingSqlCommand command = m_database.Query(sql)) 182 using (SqlConnection conn = new SqlConnection(m_connectionString))
183 using (SqlCommand command = new SqlCommand(sql, conn))
194 { 184 {
195 int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000); 185 int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
196 command.Parameters.Add(m_database.CreateParameter("id", asset.FullID)); 186 command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
@@ -202,7 +192,7 @@ namespace OpenSim.Data.MSSQL
202 command.Parameters.Add(m_database.CreateParameter("access_time", now)); 192 command.Parameters.Add(m_database.CreateParameter("access_time", now));
203 command.Parameters.Add(m_database.CreateParameter("create_time", now)); 193 command.Parameters.Add(m_database.CreateParameter("create_time", now));
204 command.Parameters.Add(m_database.CreateParameter("data", asset.Data)); 194 command.Parameters.Add(m_database.CreateParameter("data", asset.Data));
205 195 conn.Open();
206 try 196 try
207 { 197 {
208 command.ExecuteNonQuery(); 198 command.ExecuteNonQuery();
@@ -238,7 +228,8 @@ namespace OpenSim.Data.MSSQL
238 m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on update"); 228 m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on update");
239 } 229 }
240 230
241 using (AutoClosingSqlCommand command = m_database.Query(sql)) 231 using (SqlConnection conn = new SqlConnection(m_connectionString))
232 using (SqlCommand command = new SqlCommand(sql, conn))
242 { 233 {
243 command.Parameters.Add(m_database.CreateParameter("id", asset.FullID)); 234 command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
244 command.Parameters.Add(m_database.CreateParameter("name", assetName)); 235 command.Parameters.Add(m_database.CreateParameter("name", assetName));
@@ -248,7 +239,7 @@ namespace OpenSim.Data.MSSQL
248 command.Parameters.Add(m_database.CreateParameter("temporary", asset.Temporary)); 239 command.Parameters.Add(m_database.CreateParameter("temporary", asset.Temporary));
249 command.Parameters.Add(m_database.CreateParameter("data", asset.Data)); 240 command.Parameters.Add(m_database.CreateParameter("data", asset.Data));
250 command.Parameters.Add(m_database.CreateParameter("@keyId", asset.FullID)); 241 command.Parameters.Add(m_database.CreateParameter("@keyId", asset.FullID));
251 242 conn.Open();
252 try 243 try
253 { 244 {
254 command.ExecuteNonQuery(); 245 command.ExecuteNonQuery();
@@ -307,13 +298,14 @@ namespace OpenSim.Data.MSSQL
307 string sql = @"SELECT (name,description,assetType,temporary,id), Row = ROW_NUMBER() 298 string sql = @"SELECT (name,description,assetType,temporary,id), Row = ROW_NUMBER()
308 OVER (ORDER BY (some column to order by)) 299 OVER (ORDER BY (some column to order by))
309 WHERE Row >= @Start AND Row < @Start + @Count"; 300 WHERE Row >= @Start AND Row < @Start + @Count";
310
311 using (AutoClosingSqlCommand command = m_database.Query(sql))
312 {
313 command.Parameters.Add(m_database.CreateParameter("start", start));
314 command.Parameters.Add(m_database.CreateParameter("count", count));
315 301
316 using (SqlDataReader reader = command.ExecuteReader()) 302 using (SqlConnection conn = new SqlConnection(m_connectionString))
303 using (SqlCommand cmd = new SqlCommand(sql, conn))
304 {
305 cmd.Parameters.Add(m_database.CreateParameter("start", start));
306 cmd.Parameters.Add(m_database.CreateParameter("count", count));
307 conn.Open();
308 using (SqlDataReader reader = cmd.ExecuteReader())
317 { 309 {
318 while (reader.Read()) 310 while (reader.Read())
319 { 311 {
diff --git a/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs b/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs
index 801610a..1ae78c4 100644
--- a/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs
@@ -53,6 +53,7 @@ namespace OpenSim.Data.MSSQL
53 { 53 {
54 conn.Open(); 54 conn.Open();
55 Migration m = new Migration(conn, GetType().Assembly, "AuthStore"); 55 Migration m = new Migration(conn, GetType().Assembly, "AuthStore");
56 m_database = new MSSQLManager(m_ConnectionString);
56 m.Update(); 57 m.Update();
57 } 58 }
58 } 59 }
@@ -168,13 +169,14 @@ namespace OpenSim.Data.MSSQL
168 { 169 {
169 if (System.Environment.TickCount - m_LastExpire > 30000) 170 if (System.Environment.TickCount - m_LastExpire > 30000)
170 DoExpire(); 171 DoExpire();
171 string sql = "insert into tokens (UUID, token, validity) values (@principalID, @token, date_add(now(), interval @lifetime minute))"; 172
173 string sql = "insert into tokens (UUID, token, validity) values (@principalID, @token, @lifetime)";
172 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 174 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
173 using (SqlCommand cmd = new SqlCommand(sql, conn)) 175 using (SqlCommand cmd = new SqlCommand(sql, conn))
174 { 176 {
175 cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); 177 cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
176 cmd.Parameters.Add(m_database.CreateParameter("@token", token)); 178 cmd.Parameters.Add(m_database.CreateParameter("@token", token));
177 cmd.Parameters.Add(m_database.CreateParameter("@lifetime", lifetime)); 179 cmd.Parameters.Add(m_database.CreateParameter("@lifetime", DateTime.Now.AddMinutes(lifetime)));
178 conn.Open(); 180 conn.Open();
179 181
180 if (cmd.ExecuteNonQuery() > 0) 182 if (cmd.ExecuteNonQuery() > 0)
@@ -189,13 +191,15 @@ namespace OpenSim.Data.MSSQL
189 { 191 {
190 if (System.Environment.TickCount - m_LastExpire > 30000) 192 if (System.Environment.TickCount - m_LastExpire > 30000)
191 DoExpire(); 193 DoExpire();
192 string sql = "update tokens set validity = date_add(now(), interval @lifetime minute) where UUID = @principalID and token = @token and validity > now()"; 194
195 DateTime validDate = DateTime.Now.AddMinutes(lifetime);
196 string sql = "update tokens set validity = @validDate where UUID = @principalID and token = @token and validity > GetDate()";
193 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 197 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
194 using (SqlCommand cmd = new SqlCommand(sql, conn)) 198 using (SqlCommand cmd = new SqlCommand(sql, conn))
195 { 199 {
196 cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); 200 cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
197 cmd.Parameters.Add(m_database.CreateParameter("@token", token)); 201 cmd.Parameters.Add(m_database.CreateParameter("@token", token));
198 cmd.Parameters.Add(m_database.CreateParameter("@lifetime", lifetime)); 202 cmd.Parameters.Add(m_database.CreateParameter("@validDate", validDate));
199 conn.Open(); 203 conn.Open();
200 204
201 if (cmd.ExecuteNonQuery() > 0) 205 if (cmd.ExecuteNonQuery() > 0)
@@ -208,11 +212,13 @@ namespace OpenSim.Data.MSSQL
208 212
209 private void DoExpire() 213 private void DoExpire()
210 { 214 {
211 string sql = "delete from tokens where validity < now()"; 215 DateTime currentDateTime = DateTime.Now;
216 string sql = "delete from tokens where validity < @currentDateTime";
212 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 217 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
213 using (SqlCommand cmd = new SqlCommand(sql, conn)) 218 using (SqlCommand cmd = new SqlCommand(sql, conn))
214 { 219 {
215 conn.Open(); 220 conn.Open();
221 cmd.Parameters.Add(m_database.CreateParameter("@currentDateTime", currentDateTime));
216 cmd.ExecuteNonQuery(); 222 cmd.ExecuteNonQuery();
217 } 223 }
218 m_LastExpire = System.Environment.TickCount; 224 m_LastExpire = System.Environment.TickCount;
diff --git a/OpenSim/Data/MSSQL/MSSQLAvatarData.cs b/OpenSim/Data/MSSQL/MSSQLAvatarData.cs
new file mode 100644
index 0000000..49a6b09
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLAvatarData.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using System.Data.SqlClient;
37
38namespace OpenSim.Data.MSSQL
39{
40 /// <summary>
41 /// A MSSQL Interface for Avatar Storage
42 /// </summary>
43 public class MSSQLAvatarData : MSSQLGenericTableHandler<AvatarBaseData>,
44 IAvatarData
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public MSSQLAvatarData(string connectionString, string realm) :
49 base(connectionString, realm, "Avatar")
50 {
51 }
52
53 public bool Delete(UUID principalID, string name)
54 {
55 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
56 using (SqlCommand cmd = new SqlCommand())
57 {
58
59 cmd.CommandText = String.Format("DELETE FROM {0} where [PrincipalID] = @PrincipalID and [Name] = @Name", m_Realm);
60 cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
61 cmd.Parameters.Add(m_database.CreateParameter("@Name", name));
62 cmd.Connection = conn;
63 conn.Open();
64 if (cmd.ExecuteNonQuery() > 0)
65 return true;
66
67 return false;
68 }
69 }
70 }
71}
diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
index c0c6349..474f706 100644
--- a/OpenSim/Data/MSSQL/MSSQLEstateData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
@@ -44,7 +44,7 @@ namespace OpenSim.Data.MSSQL
44 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 private MSSQLManager _Database; 46 private MSSQLManager _Database;
47 47 private string m_connectionString;
48 private FieldInfo[] _Fields; 48 private FieldInfo[] _Fields;
49 private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>(); 49 private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>();
50 50
@@ -58,22 +58,9 @@ namespace OpenSim.Data.MSSQL
58 { 58 {
59 if (!string.IsNullOrEmpty(connectionString)) 59 if (!string.IsNullOrEmpty(connectionString))
60 { 60 {
61 m_connectionString = connectionString;
61 _Database = new MSSQLManager(connectionString); 62 _Database = new MSSQLManager(connectionString);
62 } 63 }
63 else
64 {
65 //TODO when can this be deleted
66 IniFile iniFile = new IniFile("mssql_connection.ini");
67 string settingDataSource = iniFile.ParseFileReadValue("data_source");
68 string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog");
69 string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info");
70 string settingUserId = iniFile.ParseFileReadValue("user_id");
71 string settingPassword = iniFile.ParseFileReadValue("password");
72
73 _Database =
74 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
75 settingPassword);
76 }
77 64
78 //Migration settings 65 //Migration settings
79 _Database.CheckMigration(_migrationStore); 66 _Database.CheckMigration(_migrationStore);
@@ -96,18 +83,18 @@ namespace OpenSim.Data.MSSQL
96 /// </summary> 83 /// </summary>
97 /// <param name="regionID">region ID.</param> 84 /// <param name="regionID">region ID.</param>
98 /// <returns></returns> 85 /// <returns></returns>
99 public EstateSettings LoadEstateSettings(UUID regionID) 86 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
100 { 87 {
101 EstateSettings es = new EstateSettings(); 88 EstateSettings es = new EstateSettings();
102 89
103 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"; 90 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";
104 91
105 bool insertEstate = false; 92 bool insertEstate = false;
106 93 using (SqlConnection conn = new SqlConnection(m_connectionString))
107 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 94 using (SqlCommand cmd = new SqlCommand(sql, conn))
108 { 95 {
109 cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID)); 96 cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
110 97 conn.Open();
111 using (SqlDataReader reader = cmd.ExecuteReader()) 98 using (SqlDataReader reader = cmd.ExecuteReader())
112 { 99 {
113 if (reader.Read()) 100 if (reader.Read())
@@ -124,7 +111,7 @@ namespace OpenSim.Data.MSSQL
124 } 111 }
125 else if (_FieldMap[name].GetValue(es) is UUID) 112 else if (_FieldMap[name].GetValue(es) is UUID)
126 { 113 {
127 _FieldMap[name].SetValue(es, new UUID((Guid) reader[name])); // uuid); 114 _FieldMap[name].SetValue(es, new UUID((Guid)reader[name])); // uuid);
128 } 115 }
129 else 116 else
130 { 117 {
@@ -140,7 +127,7 @@ namespace OpenSim.Data.MSSQL
140 } 127 }
141 128
142 129
143 if (insertEstate) 130 if (insertEstate && create)
144 { 131 {
145 List<string> names = new List<string>(FieldList); 132 List<string> names = new List<string>(FieldList);
146 133
@@ -149,34 +136,36 @@ namespace OpenSim.Data.MSSQL
149 sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray())); 136 sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
150 137
151 //_Log.Debug("[DB ESTATE]: SQL: " + sql); 138 //_Log.Debug("[DB ESTATE]: SQL: " + sql);
152 using (SqlConnection connection = _Database.DatabaseConnection()) 139 using (SqlConnection conn = new SqlConnection(m_connectionString))
140 using (SqlCommand insertCommand = new SqlCommand(sql, conn))
153 { 141 {
154 using (SqlCommand insertCommand = connection.CreateCommand()) 142 insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
155 {
156 insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
157 143
158 foreach (string name in names) 144 foreach (string name in names)
159 { 145 {
160 insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es))); 146 insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
161 }
162 SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
163 idParameter.Direction = ParameterDirection.Output;
164 insertCommand.Parameters.Add(idParameter);
165
166 insertCommand.ExecuteNonQuery();
167
168 es.EstateID = Convert.ToUInt32(idParameter.Value);
169 } 147 }
148 SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
149 idParameter.Direction = ParameterDirection.Output;
150 insertCommand.Parameters.Add(idParameter);
151 conn.Open();
152 insertCommand.ExecuteNonQuery();
153
154 es.EstateID = Convert.ToUInt32(idParameter.Value);
170 } 155 }
171 156
172 using (AutoClosingSqlCommand cmd = _Database.Query("INSERT INTO [estate_map] ([RegionID] ,[EstateID]) VALUES (@RegionID, @EstateID)")) 157 sql = "INSERT INTO [estate_map] ([RegionID] ,[EstateID]) VALUES (@RegionID, @EstateID)";
158 using (SqlConnection conn = new SqlConnection(m_connectionString))
159 using (SqlCommand cmd = new SqlCommand(sql, conn))
173 { 160 {
161
174 cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID)); 162 cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
175 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); 163 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
176 // This will throw on dupe key 164 // This will throw on dupe key
177 try 165 try
178 { 166 {
179 cmd.ExecuteNonQuery(); 167 conn.Open();
168 cmd.ExecuteNonQuery();
180 } 169 }
181 catch (Exception e) 170 catch (Exception e)
182 { 171 {
@@ -184,23 +173,6 @@ namespace OpenSim.Data.MSSQL
184 } 173 }
185 } 174 }
186 175
187 // Munge and transfer the ban list
188
189 sql = string.Format("insert into estateban select {0}, bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = @UUID", es.EstateID);
190 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
191 {
192 cmd.Parameters.Add(_Database.CreateParameter("@UUID", regionID));
193 try
194 {
195
196 cmd.ExecuteNonQuery();
197 }
198 catch (Exception)
199 {
200 _Log.Debug("[ESTATE DB]: Error setting up estateban from regionban");
201 }
202 }
203
204 //TODO check if this is needed?? 176 //TODO check if this is needed??
205 es.Save(); 177 es.Save();
206 } 178 }
@@ -226,7 +198,7 @@ namespace OpenSim.Data.MSSQL
226 198
227 names.Remove("EstateID"); 199 names.Remove("EstateID");
228 200
229 string sql = string.Format("UPDATE estate_settings SET ") ; 201 string sql = string.Format("UPDATE estate_settings SET ");
230 foreach (string name in names) 202 foreach (string name in names)
231 { 203 {
232 sql += name + " = @" + name + ", "; 204 sql += name + " = @" + name + ", ";
@@ -234,7 +206,8 @@ namespace OpenSim.Data.MSSQL
234 sql = sql.Remove(sql.LastIndexOf(",")); 206 sql = sql.Remove(sql.LastIndexOf(","));
235 sql += " WHERE EstateID = @EstateID"; 207 sql += " WHERE EstateID = @EstateID";
236 208
237 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 209 using (SqlConnection conn = new SqlConnection(m_connectionString))
210 using (SqlCommand cmd = new SqlCommand(sql, conn))
238 { 211 {
239 foreach (string name in names) 212 foreach (string name in names)
240 { 213 {
@@ -242,6 +215,7 @@ namespace OpenSim.Data.MSSQL
242 } 215 }
243 216
244 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); 217 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
218 conn.Open();
245 cmd.ExecuteNonQuery(); 219 cmd.ExecuteNonQuery();
246 } 220 }
247 221
@@ -266,12 +240,13 @@ namespace OpenSim.Data.MSSQL
266 240
267 string sql = "select bannedUUID from estateban where EstateID = @EstateID"; 241 string sql = "select bannedUUID from estateban where EstateID = @EstateID";
268 242
269 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 243 using (SqlConnection conn = new SqlConnection(m_connectionString))
244 using (SqlCommand cmd = new SqlCommand(sql, conn))
270 { 245 {
271 SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int); 246 SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int);
272 idParameter.Value = es.EstateID; 247 idParameter.Value = es.EstateID;
273 cmd.Parameters.Add(idParameter); 248 cmd.Parameters.Add(idParameter);
274 249 conn.Open();
275 using (SqlDataReader reader = cmd.ExecuteReader()) 250 using (SqlDataReader reader = cmd.ExecuteReader())
276 { 251 {
277 while (reader.Read()) 252 while (reader.Read())
@@ -293,10 +268,11 @@ namespace OpenSim.Data.MSSQL
293 268
294 string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table); 269 string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table);
295 270
296 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 271 using (SqlConnection conn = new SqlConnection(m_connectionString))
272 using (SqlCommand cmd = new SqlCommand(sql, conn))
297 { 273 {
298 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID)); 274 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
299 275 conn.Open();
300 using (SqlDataReader reader = cmd.ExecuteReader()) 276 using (SqlDataReader reader = cmd.ExecuteReader())
301 { 277 {
302 while (reader.Read()) 278 while (reader.Read())
@@ -313,20 +289,24 @@ namespace OpenSim.Data.MSSQL
313 { 289 {
314 //Delete first 290 //Delete first
315 string sql = "delete from estateban where EstateID = @EstateID"; 291 string sql = "delete from estateban where EstateID = @EstateID";
316 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 292 using (SqlConnection conn = new SqlConnection(m_connectionString))
293 using (SqlCommand cmd = new SqlCommand(sql, conn))
317 { 294 {
318 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); 295 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
296 conn.Open();
319 cmd.ExecuteNonQuery(); 297 cmd.ExecuteNonQuery();
320 } 298 }
321 299
322 //Insert after 300 //Insert after
323 sql = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )"; 301 sql = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )";
324 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 302 using (SqlConnection conn = new SqlConnection(m_connectionString))
303 using (SqlCommand cmd = new SqlCommand(sql, conn))
325 { 304 {
326 foreach (EstateBan b in es.EstateBans) 305 foreach (EstateBan b in es.EstateBans)
327 { 306 {
328 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); 307 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
329 cmd.Parameters.Add(_Database.CreateParameter("@bannedUUID", b.BannedUserID)); 308 cmd.Parameters.Add(_Database.CreateParameter("@bannedUUID", b.BannedUserID));
309 conn.Open();
330 cmd.ExecuteNonQuery(); 310 cmd.ExecuteNonQuery();
331 cmd.Parameters.Clear(); 311 cmd.Parameters.Clear();
332 } 312 }
@@ -337,14 +317,16 @@ namespace OpenSim.Data.MSSQL
337 { 317 {
338 //Delete first 318 //Delete first
339 string sql = string.Format("delete from {0} where EstateID = @EstateID", table); 319 string sql = string.Format("delete from {0} where EstateID = @EstateID", table);
340 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 320 using (SqlConnection conn = new SqlConnection(m_connectionString))
321 using (SqlCommand cmd = new SqlCommand(sql, conn))
341 { 322 {
342 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID)); 323 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
343 cmd.ExecuteNonQuery(); 324 cmd.ExecuteNonQuery();
344 } 325 }
345 326
346 sql = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table); 327 sql = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table);
347 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 328 using (SqlConnection conn = new SqlConnection(m_connectionString))
329 using (SqlCommand cmd = new SqlCommand(sql, conn))
348 { 330 {
349 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID)); 331 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
350 332
@@ -359,11 +341,36 @@ namespace OpenSim.Data.MSSQL
359 } 341 }
360 else 342 else
361 cmd.Parameters["@uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works 343 cmd.Parameters["@uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works
362 344 conn.Open();
363 cmd.ExecuteNonQuery(); 345 cmd.ExecuteNonQuery();
364 } 346 }
365 } 347 }
366 } 348 }
349
350 public EstateSettings LoadEstateSettings(int estateID)
351 {
352 return new EstateSettings();
353 }
354
355 public List<int> GetEstates(string search)
356 {
357 return new List<int>();
358 }
359
360 public bool LinkRegion(UUID regionID, int estateID)
361 {
362 return false;
363 }
364
365 public List<UUID> GetRegions(int estateID)
366 {
367 return new List<UUID>();
368 }
369
370 public bool DeleteEstate(int estateID)
371 {
372 return false;
373 }
367 #endregion 374 #endregion
368 } 375 }
369} 376}
diff --git a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
new file mode 100644
index 0000000..af4fd9b
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using System.Data.SqlClient;
35using System.Reflection;
36using System.Text;
37
38namespace OpenSim.Data.MSSQL
39{
40 public class MSSQLFriendsData : MSSQLGenericTableHandler<FriendsData>, IFriendsData
41 {
42 public MSSQLFriendsData(string connectionString, string realm)
43 : base(connectionString, realm, "FriendsStore")
44 {
45 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
46 {
47 conn.Open();
48 Migration m = new Migration(conn, GetType().Assembly, "FriendsStore");
49 m.Update();
50 }
51 }
52
53 public bool Delete(UUID principalID, string friend)
54 {
55 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
56 using (SqlCommand cmd = new SqlCommand())
57 {
58 cmd.CommandText = String.Format("delete from {0} where PrincipalID = @PrincipalID and Friend = @Friend", m_Realm);
59 cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
60 cmd.Parameters.Add(m_database.CreateParameter("@Friend", friend));
61 cmd.Connection = conn;
62 conn.Open();
63 cmd.ExecuteNonQuery();
64
65 return true;
66 }
67 }
68
69 public FriendsData[] GetFriends(UUID principalID)
70 {
71 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
72 using (SqlCommand cmd = new SqlCommand())
73 {
74
75 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = @PrincipalID", m_Realm);
76 cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
77 cmd.Connection = conn;
78 conn.Open();
79 return DoQuery(cmd);
80 }
81 }
82 }
83}
diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
new file mode 100644
index 0000000..904366e
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
@@ -0,0 +1,359 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using System.Data.SqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using System.Text;
38
39namespace OpenSim.Data.MSSQL
40{
41 public class MSSQLGenericTableHandler<T> where T : class, new()
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 protected string m_ConnectionString;
47 protected MSSQLManager m_database; //used for parameter type translation
48 protected Dictionary<string, FieldInfo> m_Fields =
49 new Dictionary<string, FieldInfo>();
50
51 protected List<string> m_ColumnNames = null;
52 protected string m_Realm;
53 protected FieldInfo m_DataField = null;
54
55 public MSSQLGenericTableHandler(string connectionString,
56 string realm, string storeName)
57 {
58 m_Realm = realm;
59
60 if (storeName != String.Empty)
61 {
62 Assembly assem = GetType().Assembly;
63 m_ConnectionString = connectionString;
64 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
65 {
66 conn.Open();
67 Migration m = new Migration(conn, assem, storeName);
68 m.Update();
69 }
70
71 }
72 m_database = new MSSQLManager(m_ConnectionString);
73
74 Type t = typeof(T);
75 FieldInfo[] fields = t.GetFields(BindingFlags.Public |
76 BindingFlags.Instance |
77 BindingFlags.DeclaredOnly);
78
79 if (fields.Length == 0)
80 return;
81
82 foreach (FieldInfo f in fields)
83 {
84 if (f.Name != "Data")
85 m_Fields[f.Name] = f;
86 else
87 m_DataField = f;
88 }
89
90 }
91
92 private void CheckColumnNames(SqlDataReader reader)
93 {
94 if (m_ColumnNames != null)
95 return;
96
97 m_ColumnNames = new List<string>();
98
99 DataTable schemaTable = reader.GetSchemaTable();
100 foreach (DataRow row in schemaTable.Rows)
101 {
102 if (row["ColumnName"] != null &&
103 (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
104 m_ColumnNames.Add(row["ColumnName"].ToString());
105
106 }
107 }
108
109 private List<string> GetConstraints()
110 {
111 List<string> constraints = new List<string>();
112 string query = string.Format(@"SELECT
113 COL_NAME(ic.object_id,ic.column_id) AS column_name
114 FROM sys.indexes AS i
115 INNER JOIN sys.index_columns AS ic
116 ON i.object_id = ic.object_id AND i.index_id = ic.index_id
117 WHERE i.is_primary_key = 1
118 AND i.object_id = OBJECT_ID('{0}');", m_Realm);
119 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
120 using (SqlCommand cmd = new SqlCommand(query, conn))
121 {
122 conn.Open();
123 using (SqlDataReader rdr = cmd.ExecuteReader())
124 {
125 while (rdr.Read())
126 {
127 // query produces 0 to many rows of single column, so always add the first item in each row
128 constraints.Add((string)rdr[0]);
129 }
130 }
131 return constraints;
132 }
133 }
134
135 public virtual T[] Get(string field, string key)
136 {
137 return Get(new string[] { field }, new string[] { key });
138 }
139
140 public virtual T[] Get(string[] fields, string[] keys)
141 {
142 if (fields.Length != keys.Length)
143 return new T[0];
144
145 List<string> terms = new List<string>();
146
147 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
148 using (SqlCommand cmd = new SqlCommand())
149 {
150
151 for (int i = 0; i < fields.Length; i++)
152 {
153 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
154 terms.Add("[" + fields[i] + "] = @" + fields[i]);
155 }
156
157 string where = String.Join(" AND ", terms.ToArray());
158
159 string query = String.Format("SELECT * FROM {0} WHERE {1}",
160 m_Realm, where);
161
162 cmd.Connection = conn;
163 cmd.CommandText = query;
164 conn.Open();
165 return DoQuery(cmd);
166 }
167 }
168
169 protected T[] DoQuery(SqlCommand cmd)
170 {
171 using (SqlDataReader reader = cmd.ExecuteReader())
172 {
173 if (reader == null)
174 return new T[0];
175
176 CheckColumnNames(reader);
177
178 List<T> result = new List<T>();
179
180 while (reader.Read())
181 {
182 T row = new T();
183
184 foreach (string name in m_Fields.Keys)
185 {
186 if (m_Fields[name].GetValue(row) is bool)
187 {
188 int v = Convert.ToInt32(reader[name]);
189 m_Fields[name].SetValue(row, v != 0 ? true : false);
190 }
191 else if (m_Fields[name].GetValue(row) is UUID)
192 {
193 UUID uuid = UUID.Zero;
194
195 UUID.TryParse(reader[name].ToString(), out uuid);
196 m_Fields[name].SetValue(row, uuid);
197 }
198 else if (m_Fields[name].GetValue(row) is int)
199 {
200 int v = Convert.ToInt32(reader[name]);
201 m_Fields[name].SetValue(row, v);
202 }
203 else
204 {
205 m_Fields[name].SetValue(row, reader[name]);
206 }
207 }
208
209 if (m_DataField != null)
210 {
211 Dictionary<string, string> data =
212 new Dictionary<string, string>();
213
214 foreach (string col in m_ColumnNames)
215 {
216 data[col] = reader[col].ToString();
217 if (data[col] == null)
218 data[col] = String.Empty;
219 }
220
221 m_DataField.SetValue(row, data);
222 }
223
224 result.Add(row);
225 }
226 return result.ToArray();
227 }
228 }
229
230 public virtual T[] Get(string where)
231 {
232 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
233 using (SqlCommand cmd = new SqlCommand())
234 {
235
236 string query = String.Format("SELECT * FROM {0} WHERE {1}",
237 m_Realm, where);
238 cmd.Connection = conn;
239 cmd.CommandText = query;
240
241 //m_log.WarnFormat("[MSSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
242
243 conn.Open();
244 return DoQuery(cmd);
245 }
246 }
247
248 public virtual bool Store(T row)
249 {
250 List<string> constraintFields = GetConstraints();
251 List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>();
252
253 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
254 using (SqlCommand cmd = new SqlCommand())
255 {
256
257 StringBuilder query = new StringBuilder();
258 List<String> names = new List<String>();
259 List<String> values = new List<String>();
260
261 foreach (FieldInfo fi in m_Fields.Values)
262 {
263 names.Add(fi.Name);
264 values.Add("@" + fi.Name);
265 if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
266 {
267 constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
268 }
269 cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row).ToString()));
270 }
271
272 if (m_DataField != null)
273 {
274 Dictionary<string, string> data =
275 (Dictionary<string, string>)m_DataField.GetValue(row);
276
277 foreach (KeyValuePair<string, string> kvp in data)
278 {
279 if (constraintFields.Count > 0 && constraintFields.Contains(kvp.Key))
280 {
281 constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key));
282 }
283 names.Add(kvp.Key);
284 values.Add("@" + kvp.Key);
285 cmd.Parameters.Add(m_database.CreateParameter("@" + kvp.Key, kvp.Value));
286 }
287
288 }
289
290 query.AppendFormat("UPDATE {0} SET ", m_Realm);
291 int i = 0;
292 for (i = 0; i < names.Count - 1; i++)
293 {
294 query.AppendFormat("[{0}] = {1}, ", names[i], values[i]);
295 }
296 query.AppendFormat("[{0}] = {1} ", names[i], values[i]);
297 if (constraints.Count > 0)
298 {
299 List<string> terms = new List<string>();
300 for (int j = 0; j < constraints.Count; j++)
301 {
302 terms.Add(" [" + constraints[j].Key + "] = @" + constraints[j].Key);
303 }
304 string where = String.Join(" AND ", terms.ToArray());
305 query.AppendFormat(" WHERE {0} ", where);
306
307 }
308 cmd.Connection = conn;
309 cmd.CommandText = query.ToString();
310
311 conn.Open();
312 if (cmd.ExecuteNonQuery() > 0)
313 {
314 //m_log.WarnFormat("[MSSQLGenericTable]: Updating {0}", m_Realm);
315 return true;
316 }
317 else
318 {
319 // assume record has not yet been inserted
320
321 query = new StringBuilder();
322 query.AppendFormat("INSERT INTO {0} ([", m_Realm);
323 query.Append(String.Join("],[", names.ToArray()));
324 query.Append("]) values (" + String.Join(",", values.ToArray()) + ")");
325 cmd.Connection = conn;
326 cmd.CommandText = query.ToString();
327 //m_log.WarnFormat("[MSSQLGenericTable]: Inserting into {0}", m_Realm);
328 if (conn.State != ConnectionState.Open)
329 conn.Open();
330 if (cmd.ExecuteNonQuery() > 0)
331 return true;
332 }
333
334 return false;
335 }
336 }
337
338 public virtual bool Delete(string field, string val)
339 {
340 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
341 using (SqlCommand cmd = new SqlCommand())
342 {
343 string deleteCommand = String.Format("DELETE FROM {0} WHERE [{1}] = @{1}", m_Realm, field);
344 cmd.CommandText = deleteCommand;
345
346 cmd.Parameters.Add(m_database.CreateParameter(field, val));
347 cmd.Connection = conn;
348 conn.Open();
349
350 if (cmd.ExecuteNonQuery() > 0)
351 {
352 //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
353 return true;
354 }
355 return false;
356 }
357 }
358 }
359}
diff --git a/OpenSim/Data/MSSQL/MSSQLGridData.cs b/OpenSim/Data/MSSQL/MSSQLGridData.cs
deleted file mode 100644
index 8a3d332..0000000
--- a/OpenSim/Data/MSSQL/MSSQLGridData.cs
+++ /dev/null
@@ -1,587 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Data.SqlClient;
32using System.Reflection;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37namespace OpenSim.Data.MSSQL
38{
39 /// <summary>
40 /// A grid data interface for MSSQL Server
41 /// </summary>
42 public class MSSQLGridData : GridDataBase
43 {
44 private const string _migrationStore = "GridStore";
45
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 /// <summary>
49 /// Database manager
50 /// </summary>
51 private MSSQLManager database;
52
53 private string m_regionsTableName = "regions";
54
55 #region IPlugin Members
56
57 // [Obsolete("Cannot be default-initialized!")]
58 override public void Initialise()
59 {
60 m_log.Info("[GRID DB]: " + Name + " cannot be default-initialized!");
61 throw new PluginNotInitialisedException(Name);
62 }
63
64 /// <summary>
65 /// Initialises the Grid Interface
66 /// </summary>
67 /// <param name="connectionString">connect string</param>
68 /// <remarks>use mssql_connection.ini</remarks>
69 override public void Initialise(string connectionString)
70 {
71 if (!string.IsNullOrEmpty(connectionString))
72 {
73 database = new MSSQLManager(connectionString);
74 }
75 else
76 {
77 // TODO: make the connect string actually do something
78 IniFile iniFile = new IniFile("mssql_connection.ini");
79
80 string settingDataSource = iniFile.ParseFileReadValue("data_source");
81 string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog");
82 string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info");
83 string settingUserId = iniFile.ParseFileReadValue("user_id");
84 string settingPassword = iniFile.ParseFileReadValue("password");
85
86 m_regionsTableName = iniFile.ParseFileReadValue("regionstablename");
87 if (m_regionsTableName == null)
88 {
89 m_regionsTableName = "regions";
90 }
91
92 database =
93 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
94 settingPassword);
95 }
96
97 //New migrations check of store
98 database.CheckMigration(_migrationStore);
99 }
100
101 /// <summary>
102 /// Shuts down the grid interface
103 /// </summary>
104 override public void Dispose()
105 {
106 database = null;
107 }
108
109 /// <summary>
110 /// The name of this DB provider.
111 /// </summary>
112 /// <returns>A string containing the storage system name</returns>
113 override public string Name
114 {
115 get { return "MSSQL OpenGridData"; }
116 }
117
118 /// <summary>
119 /// Database provider version.
120 /// </summary>
121 /// <returns>A string containing the storage system version</returns>
122 override public string Version
123 {
124 get { return "0.1"; }
125 }
126
127 #endregion
128
129 #region Public override GridDataBase methods
130
131 /// <summary>
132 /// Returns a list of regions within the specified ranges
133 /// </summary>
134 /// <param name="xmin">minimum X coordinate</param>
135 /// <param name="ymin">minimum Y coordinate</param>
136 /// <param name="xmax">maximum X coordinate</param>
137 /// <param name="ymax">maximum Y coordinate</param>
138 /// <returns>null</returns>
139 /// <remarks>always return null</remarks>
140 override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax)
141 {
142 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM regions WHERE locX >= @xmin AND locX <= @xmax AND locY >= @ymin AND locY <= @ymax"))
143 {
144 command.Parameters.Add(database.CreateParameter("xmin", xmin));
145 command.Parameters.Add(database.CreateParameter("ymin", ymin));
146 command.Parameters.Add(database.CreateParameter("xmax", xmax));
147 command.Parameters.Add(database.CreateParameter("ymax", ymax));
148
149 List<RegionProfileData> rows = new List<RegionProfileData>();
150
151 using (SqlDataReader reader = command.ExecuteReader())
152 {
153 while (reader.Read())
154 {
155 rows.Add(ReadSimRow(reader));
156 }
157 }
158
159 if (rows.Count > 0)
160 {
161 return rows.ToArray();
162 }
163 }
164 m_log.Info("[GRID DB] : Found no regions within range.");
165 return null;
166 }
167
168
169 /// <summary>
170 /// Returns up to maxNum profiles of regions that have a name starting with namePrefix
171 /// </summary>
172 /// <param name="namePrefix">The name to match against</param>
173 /// <param name="maxNum">Maximum number of profiles to return</param>
174 /// <returns>A list of sim profiles</returns>
175 override public List<RegionProfileData> GetRegionsByName (string namePrefix, uint maxNum)
176 {
177 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM regions WHERE regionName LIKE @name"))
178 {
179 command.Parameters.Add(database.CreateParameter("name", namePrefix + "%"));
180
181 List<RegionProfileData> rows = new List<RegionProfileData>();
182
183 using (SqlDataReader reader = command.ExecuteReader())
184 {
185 while (rows.Count < maxNum && reader.Read())
186 {
187 rows.Add(ReadSimRow(reader));
188 }
189 }
190
191 return rows;
192 }
193 }
194
195 /// <summary>
196 /// Returns a sim profile from its location
197 /// </summary>
198 /// <param name="handle">Region location handle</param>
199 /// <returns>Sim profile</returns>
200 override public RegionProfileData GetProfileByHandle(ulong handle)
201 {
202 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE regionHandle = @handle"))
203 {
204 command.Parameters.Add(database.CreateParameter("handle", handle));
205
206 using (SqlDataReader reader = command.ExecuteReader())
207 {
208 if (reader.Read())
209 {
210 return ReadSimRow(reader);
211 }
212 }
213 }
214 m_log.InfoFormat("[GRID DB] : No region found with handle : {0}", handle);
215 return null;
216 }
217
218 /// <summary>
219 /// Returns a sim profile from its UUID
220 /// </summary>
221 /// <param name="uuid">The region UUID</param>
222 /// <returns>The sim profile</returns>
223 override public RegionProfileData GetProfileByUUID(UUID uuid)
224 {
225 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE uuid = @uuid"))
226 {
227 command.Parameters.Add(database.CreateParameter("uuid", uuid));
228
229 using (SqlDataReader reader = command.ExecuteReader())
230 {
231 if (reader.Read())
232 {
233 return ReadSimRow(reader);
234 }
235 }
236 }
237 m_log.InfoFormat("[GRID DB] : No region found with UUID : {0}", uuid);
238 return null;
239 }
240
241 /// <summary>
242 /// Returns a sim profile from it's Region name string
243 /// </summary>
244 /// <param name="regionName">The region name search query</param>
245 /// <returns>The sim profile</returns>
246 override public RegionProfileData GetProfileByString(string regionName)
247 {
248 if (regionName.Length > 2)
249 {
250 using (AutoClosingSqlCommand command = database.Query("SELECT top 1 * FROM " + m_regionsTableName + " WHERE regionName like @regionName order by regionName"))
251 {
252 command.Parameters.Add(database.CreateParameter("regionName", regionName + "%"));
253
254 using (SqlDataReader reader = command.ExecuteReader())
255 {
256 if (reader.Read())
257 {
258 return ReadSimRow(reader);
259 }
260 }
261 }
262 m_log.InfoFormat("[GRID DB] : No region found with regionName : {0}", regionName);
263 return null;
264 }
265
266 m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters");
267 return null;
268 }
269
270 /// <summary>
271 /// Adds a new specified region to the database
272 /// </summary>
273 /// <param name="profile">The profile to add</param>
274 /// <returns>A dataresponse enum indicating success</returns>
275 override public DataResponse StoreProfile(RegionProfileData profile)
276 {
277 if (GetProfileByUUID(profile.UUID) == null)
278 {
279 if (InsertRegionRow(profile))
280 {
281 return DataResponse.RESPONSE_OK;
282 }
283 }
284 else
285 {
286 if (UpdateRegionRow(profile))
287 {
288 return DataResponse.RESPONSE_OK;
289 }
290 }
291
292 return DataResponse.RESPONSE_ERROR;
293 }
294
295 /// <summary>
296 /// Deletes a sim profile from the database
297 /// </summary>
298 /// <param name="uuid">the sim UUID</param>
299 /// <returns>Successful?</returns>
300 //public DataResponse DeleteProfile(RegionProfileData profile)
301 override public DataResponse DeleteProfile(string uuid)
302 {
303 using (AutoClosingSqlCommand command = database.Query("DELETE FROM regions WHERE uuid = @uuid;"))
304 {
305 command.Parameters.Add(database.CreateParameter("uuid", uuid));
306 try
307 {
308 command.ExecuteNonQuery();
309 return DataResponse.RESPONSE_OK;
310 }
311 catch (Exception e)
312 {
313 m_log.DebugFormat("[GRID DB] : Error deleting region info, error is : {0}", e.Message);
314 return DataResponse.RESPONSE_ERROR;
315 }
316 }
317 }
318
319 #endregion
320
321 #region Methods that are not used or deprecated (still needed because of base class)
322
323 /// <summary>
324 /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret.
325 /// </summary>
326 /// <param name="uuid">The UUID of the challenger</param>
327 /// <param name="handle">The attempted regionHandle of the challenger</param>
328 /// <param name="authkey">The secret</param>
329 /// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
330 override public bool AuthenticateSim(UUID uuid, ulong handle, string authkey)
331 {
332 bool throwHissyFit = false; // Should be true by 1.0
333
334 if (throwHissyFit)
335 throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
336
337 RegionProfileData data = GetProfileByUUID(uuid);
338
339 return (handle == data.regionHandle && authkey == data.regionSecret);
340 }
341
342 /// <summary>
343 /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
344 /// </summary>
345 /// <remarks>This requires a security audit.</remarks>
346 /// <param name="uuid"></param>
347 /// <param name="handle"></param>
348 /// <param name="authhash"></param>
349 /// <param name="challenge"></param>
350 /// <returns></returns>
351 public bool AuthenticateSim(UUID uuid, ulong handle, string authhash, string challenge)
352 {
353 // SHA512Managed HashProvider = new SHA512Managed();
354 // Encoding TextProvider = new UTF8Encoding();
355
356 // byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
357 // byte[] hash = HashProvider.ComputeHash(stream);
358 return false;
359 }
360
361 /// <summary>
362 /// NOT IMPLEMENTED
363 /// WHEN IS THIS GONNA BE IMPLEMENTED.
364 /// </summary>
365 /// <param name="x"></param>
366 /// <param name="y"></param>
367 /// <returns>null</returns>
368 override public ReservationData GetReservationAtPoint(uint x, uint y)
369 {
370 return null;
371 }
372
373 #endregion
374
375 #region private methods
376
377 /// <summary>
378 /// Reads a region row from a database reader
379 /// </summary>
380 /// <param name="reader">An active database reader</param>
381 /// <returns>A region profile</returns>
382 private static RegionProfileData ReadSimRow(IDataRecord reader)
383 {
384 RegionProfileData retval = new RegionProfileData();
385
386 // Region Main gotta-have-or-we-return-null parts
387 UInt64 tmp64;
388 if (!UInt64.TryParse(reader["regionHandle"].ToString(), out tmp64))
389 {
390 return null;
391 }
392
393 retval.regionHandle = tmp64;
394
395// UUID tmp_uuid;
396// if (!UUID.TryParse((string)reader["uuid"], out tmp_uuid))
397// {
398// return null;
399// }
400
401 retval.UUID = new UUID((Guid)reader["uuid"]); // tmp_uuid;
402
403 // non-critical parts
404 retval.regionName = reader["regionName"].ToString();
405 retval.originUUID = new UUID((Guid)reader["originUUID"]);
406
407 // Secrets
408 retval.regionRecvKey = reader["regionRecvKey"].ToString();
409 retval.regionSecret = reader["regionSecret"].ToString();
410 retval.regionSendKey = reader["regionSendKey"].ToString();
411
412 // Region Server
413 retval.regionDataURI = reader["regionDataURI"].ToString();
414 retval.regionOnline = false; // Needs to be pinged before this can be set.
415 retval.serverIP = reader["serverIP"].ToString();
416 retval.serverPort = Convert.ToUInt32(reader["serverPort"]);
417 retval.serverURI = reader["serverURI"].ToString();
418 retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString());
419 retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString());
420
421 // Location
422 retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString());
423 retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString());
424 retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString());
425
426 // Neighbours - 0 = No Override
427 retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString());
428 retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString());
429 retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString());
430 retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString());
431
432 // Assets
433 retval.regionAssetURI = reader["regionAssetURI"].ToString();
434 retval.regionAssetRecvKey = reader["regionAssetRecvKey"].ToString();
435 retval.regionAssetSendKey = reader["regionAssetSendKey"].ToString();
436
437 // Userserver
438 retval.regionUserURI = reader["regionUserURI"].ToString();
439 retval.regionUserRecvKey = reader["regionUserRecvKey"].ToString();
440 retval.regionUserSendKey = reader["regionUserSendKey"].ToString();
441
442 // World Map Addition
443 retval.regionMapTextureID = new UUID((Guid)reader["regionMapTexture"]);
444 retval.owner_uuid = new UUID((Guid)reader["owner_uuid"]);
445 retval.maturity = Convert.ToUInt32(reader["access"]);
446 return retval;
447 }
448
449 /// <summary>
450 /// Update the specified region in the database
451 /// </summary>
452 /// <param name="profile">The profile to update</param>
453 /// <returns>success ?</returns>
454 private bool UpdateRegionRow(RegionProfileData profile)
455 {
456 bool returnval = false;
457
458 //Insert new region
459 string sql =
460 "UPDATE " + m_regionsTableName + @" SET
461 [regionHandle]=@regionHandle, [regionName]=@regionName,
462 [regionRecvKey]=@regionRecvKey, [regionSecret]=@regionSecret, [regionSendKey]=@regionSendKey,
463 [regionDataURI]=@regionDataURI, [serverIP]=@serverIP, [serverPort]=@serverPort, [serverURI]=@serverURI,
464 [locX]=@locX, [locY]=@locY, [locZ]=@locZ, [eastOverrideHandle]=@eastOverrideHandle,
465 [westOverrideHandle]=@westOverrideHandle, [southOverrideHandle]=@southOverrideHandle,
466 [northOverrideHandle]=@northOverrideHandle, [regionAssetURI]=@regionAssetURI,
467 [regionAssetRecvKey]=@regionAssetRecvKey, [regionAssetSendKey]=@regionAssetSendKey,
468 [regionUserURI]=@regionUserURI, [regionUserRecvKey]=@regionUserRecvKey, [regionUserSendKey]=@regionUserSendKey,
469 [regionMapTexture]=@regionMapTexture, [serverHttpPort]=@serverHttpPort,
470 [serverRemotingPort]=@serverRemotingPort, [owner_uuid]=@owner_uuid , [originUUID]=@originUUID
471 where [uuid]=@uuid";
472
473 using (AutoClosingSqlCommand command = database.Query(sql))
474 {
475 command.Parameters.Add(database.CreateParameter("regionHandle", profile.regionHandle));
476 command.Parameters.Add(database.CreateParameter("regionName", profile.regionName));
477 command.Parameters.Add(database.CreateParameter("uuid", profile.UUID));
478 command.Parameters.Add(database.CreateParameter("regionRecvKey", profile.regionRecvKey));
479 command.Parameters.Add(database.CreateParameter("regionSecret", profile.regionSecret));
480 command.Parameters.Add(database.CreateParameter("regionSendKey", profile.regionSendKey));
481 command.Parameters.Add(database.CreateParameter("regionDataURI", profile.regionDataURI));
482 command.Parameters.Add(database.CreateParameter("serverIP", profile.serverIP));
483 command.Parameters.Add(database.CreateParameter("serverPort", profile.serverPort));
484 command.Parameters.Add(database.CreateParameter("serverURI", profile.serverURI));
485 command.Parameters.Add(database.CreateParameter("locX", profile.regionLocX));
486 command.Parameters.Add(database.CreateParameter("locY", profile.regionLocY));
487 command.Parameters.Add(database.CreateParameter("locZ", profile.regionLocZ));
488 command.Parameters.Add(database.CreateParameter("eastOverrideHandle", profile.regionEastOverrideHandle));
489 command.Parameters.Add(database.CreateParameter("westOverrideHandle", profile.regionWestOverrideHandle));
490 command.Parameters.Add(database.CreateParameter("northOverrideHandle", profile.regionNorthOverrideHandle));
491 command.Parameters.Add(database.CreateParameter("southOverrideHandle", profile.regionSouthOverrideHandle));
492 command.Parameters.Add(database.CreateParameter("regionAssetURI", profile.regionAssetURI));
493 command.Parameters.Add(database.CreateParameter("regionAssetRecvKey", profile.regionAssetRecvKey));
494 command.Parameters.Add(database.CreateParameter("regionAssetSendKey", profile.regionAssetSendKey));
495 command.Parameters.Add(database.CreateParameter("regionUserURI", profile.regionUserURI));
496 command.Parameters.Add(database.CreateParameter("regionUserRecvKey", profile.regionUserRecvKey));
497 command.Parameters.Add(database.CreateParameter("regionUserSendKey", profile.regionUserSendKey));
498 command.Parameters.Add(database.CreateParameter("regionMapTexture", profile.regionMapTextureID));
499 command.Parameters.Add(database.CreateParameter("serverHttpPort", profile.httpPort));
500 command.Parameters.Add(database.CreateParameter("serverRemotingPort", profile.remotingPort));
501 command.Parameters.Add(database.CreateParameter("owner_uuid", profile.owner_uuid));
502 command.Parameters.Add(database.CreateParameter("originUUID", profile.originUUID));
503
504 try
505 {
506 command.ExecuteNonQuery();
507 returnval = true;
508 }
509 catch (Exception e)
510 {
511 m_log.Error("[GRID DB] : Error updating region, error: " + e.Message);
512 }
513 }
514
515 return returnval;
516 }
517
518 /// <summary>
519 /// Creates a new region in the database
520 /// </summary>
521 /// <param name="profile">The region profile to insert</param>
522 /// <returns>Successful?</returns>
523 private bool InsertRegionRow(RegionProfileData profile)
524 {
525 bool returnval = false;
526
527 //Insert new region
528 string sql =
529 "INSERT INTO " + m_regionsTableName + @" ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI],
530 [serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle],
531 [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], [regionAssetSendKey],
532 [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort],
533 [serverRemotingPort], [owner_uuid], [originUUID], [access])
534 VALUES (@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI,
535 @serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle,
536 @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, @regionAssetSendKey,
537 @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort, @owner_uuid, @originUUID, @access);";
538
539 using (AutoClosingSqlCommand command = database.Query(sql))
540 {
541 command.Parameters.Add(database.CreateParameter("regionHandle", profile.regionHandle));
542 command.Parameters.Add(database.CreateParameter("regionName", profile.regionName));
543 command.Parameters.Add(database.CreateParameter("uuid", profile.UUID));
544 command.Parameters.Add(database.CreateParameter("regionRecvKey", profile.regionRecvKey));
545 command.Parameters.Add(database.CreateParameter("regionSecret", profile.regionSecret));
546 command.Parameters.Add(database.CreateParameter("regionSendKey", profile.regionSendKey));
547 command.Parameters.Add(database.CreateParameter("regionDataURI", profile.regionDataURI));
548 command.Parameters.Add(database.CreateParameter("serverIP", profile.serverIP));
549 command.Parameters.Add(database.CreateParameter("serverPort", profile.serverPort));
550 command.Parameters.Add(database.CreateParameter("serverURI", profile.serverURI));
551 command.Parameters.Add(database.CreateParameter("locX", profile.regionLocX));
552 command.Parameters.Add(database.CreateParameter("locY", profile.regionLocY));
553 command.Parameters.Add(database.CreateParameter("locZ", profile.regionLocZ));
554 command.Parameters.Add(database.CreateParameter("eastOverrideHandle", profile.regionEastOverrideHandle));
555 command.Parameters.Add(database.CreateParameter("westOverrideHandle", profile.regionWestOverrideHandle));
556 command.Parameters.Add(database.CreateParameter("northOverrideHandle", profile.regionNorthOverrideHandle));
557 command.Parameters.Add(database.CreateParameter("southOverrideHandle", profile.regionSouthOverrideHandle));
558 command.Parameters.Add(database.CreateParameter("regionAssetURI", profile.regionAssetURI));
559 command.Parameters.Add(database.CreateParameter("regionAssetRecvKey", profile.regionAssetRecvKey));
560 command.Parameters.Add(database.CreateParameter("regionAssetSendKey", profile.regionAssetSendKey));
561 command.Parameters.Add(database.CreateParameter("regionUserURI", profile.regionUserURI));
562 command.Parameters.Add(database.CreateParameter("regionUserRecvKey", profile.regionUserRecvKey));
563 command.Parameters.Add(database.CreateParameter("regionUserSendKey", profile.regionUserSendKey));
564 command.Parameters.Add(database.CreateParameter("regionMapTexture", profile.regionMapTextureID));
565 command.Parameters.Add(database.CreateParameter("serverHttpPort", profile.httpPort));
566 command.Parameters.Add(database.CreateParameter("serverRemotingPort", profile.remotingPort));
567 command.Parameters.Add(database.CreateParameter("owner_uuid", profile.owner_uuid));
568 command.Parameters.Add(database.CreateParameter("originUUID", profile.originUUID));
569 command.Parameters.Add(database.CreateParameter("access", profile.maturity));
570
571 try
572 {
573 command.ExecuteNonQuery();
574 returnval = true;
575 }
576 catch (Exception e)
577 {
578 m_log.Error("[GRID DB] : Error inserting region, error: " + e.Message);
579 }
580 }
581
582 return returnval;
583 }
584
585 #endregion
586 }
587}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGUserDataPlugin.cs b/OpenSim/Data/MSSQL/MSSQLGridUserData.cs
index 4b8fc26..9993720 100644
--- a/OpenSim/Region/Communications/Hypergrid/HGUserDataPlugin.cs
+++ b/OpenSim/Data/MSSQL/MSSQLGridUserData.cs
@@ -26,47 +26,43 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
30using System.Collections.Generic; 29using System.Collections.Generic;
31using System.Net; 30using System.Data;
32using System.Reflection; 31using System.Reflection;
33using System.Text.RegularExpressions; 32using System.Threading;
34using System.Xml.Serialization;
35using log4net; 33using log4net;
36using Nwc.XmlRpc;
37using OpenMetaverse; 34using OpenMetaverse;
38using OpenSim.Data;
39using OpenSim.Framework; 35using OpenSim.Framework;
40using OpenSim.Framework.Communications; 36using System.Data.SqlClient;
41using OpenSim.Framework.Communications.Clients;
42using OpenSim.Region.Communications.OGS1;
43 37
44namespace OpenSim.Region.Communications.Hypergrid 38namespace OpenSim.Data.MSSQL
45{ 39{
46 public class HGUserDataPlugin : OGS1UserDataPlugin 40 /// <summary>
41 /// A MSSQL Interface for Avatar Storage
42 /// </summary>
43 public class MSSQLGridUserData : MSSQLGenericTableHandler<GridUserData>,
44 IGridUserData
47 { 45 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 47
50 HGUserServices m_UserServices; 48 public MSSQLGridUserData(string connectionString, string realm) :
51 49 base(connectionString, realm, "UserGrid")
52 public HGUserDataPlugin()
53 { 50 {
54 } 51 }
55 52
56 public HGUserDataPlugin(CommunicationsManager commsManager, HGUserServices userServices) 53 public GridUserData GetGridUserData(string userID)
57 { 54 {
58 m_log.DebugFormat("[HG USER SERVICES]: {0} initialized", Name); 55 GridUserData[] ret = Get("UserID", userID);
59 m_commsManager = commsManager; 56
60 m_UserServices = userServices; 57 if (ret.Length == 0)
58 return null;
59
60 return ret[0];
61 } 61 }
62 62
63 protected override string GetUserServerURL(UUID userID) 63 public bool StoreGridUserData(GridUserData data)
64 { 64 {
65 string url = string.Empty; 65 return Store(data);
66 if (m_UserServices.IsForeignUser(userID, out url))
67 return url;
68 return m_commsManager.NetworkServersInfo.UserURL;
69 } 66 }
70
71 } 67 }
72} 68}
diff --git a/OpenSim/Data/MSSQL/MSSQLInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLInventoryData.cs
index 1482184..4815700 100644
--- a/OpenSim/Data/MSSQL/MSSQLInventoryData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLInventoryData.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Data.MSSQL
49 /// The database manager 49 /// The database manager
50 /// </summary> 50 /// </summary>
51 private MSSQLManager database; 51 private MSSQLManager database;
52 private string m_connectionString;
52 53
53 #region IPlugin members 54 #region IPlugin members
54 55
@@ -66,24 +67,9 @@ namespace OpenSim.Data.MSSQL
66 /// <remarks>use mssql_connection.ini</remarks> 67 /// <remarks>use mssql_connection.ini</remarks>
67 public void Initialise(string connectionString) 68 public void Initialise(string connectionString)
68 { 69 {
69 if (!string.IsNullOrEmpty(connectionString)) 70 m_connectionString = connectionString;
70 { 71 database = new MSSQLManager(connectionString);
71 database = new MSSQLManager(connectionString); 72
72 }
73 else
74 {
75 IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini");
76 string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source");
77 string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog");
78 string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info");
79 string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id");
80 string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password");
81
82 database =
83 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
84 settingPassword);
85 }
86
87 //New migrations check of store 73 //New migrations check of store
88 database.CheckMigration(_migrationStore); 74 database.CheckMigration(_migrationStore);
89 } 75 }
@@ -169,11 +155,13 @@ namespace OpenSim.Data.MSSQL
169 /// <returns>A folder class</returns> 155 /// <returns>A folder class</returns>
170 public InventoryFolderBase getInventoryFolder(UUID folderID) 156 public InventoryFolderBase getInventoryFolder(UUID folderID)
171 { 157 {
172 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @folderID")) 158 string sql = "SELECT * FROM inventoryfolders WHERE folderID = @folderID";
159 using (SqlConnection conn = new SqlConnection(m_connectionString))
160 using (SqlCommand cmd = new SqlCommand(sql, conn))
173 { 161 {
174 command.Parameters.Add(database.CreateParameter("folderID", folderID)); 162 cmd.Parameters.Add(database.CreateParameter("folderID", folderID));
175 163 conn.Open();
176 using (IDataReader reader = command.ExecuteReader()) 164 using (SqlDataReader reader = cmd.ExecuteReader())
177 { 165 {
178 if (reader.Read()) 166 if (reader.Read())
179 { 167 {
@@ -197,18 +185,19 @@ namespace OpenSim.Data.MSSQL
197 //Note this is changed so it opens only one connection to the database and not everytime it wants to get data. 185 //Note this is changed so it opens only one connection to the database and not everytime it wants to get data.
198 186
199 List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); 187 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
200 188 string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
201 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID")) 189 using (SqlConnection conn = new SqlConnection(m_connectionString))
190 using (SqlCommand cmd = new SqlCommand(sql, conn))
202 { 191 {
203 command.Parameters.Add(database.CreateParameter("@parentID", parentID)); 192 cmd.Parameters.Add(database.CreateParameter("@parentID", parentID));
204 193 conn.Open();
205 folders.AddRange(getInventoryFolders(command)); 194 folders.AddRange(getInventoryFolders(cmd));
206 195
207 List<InventoryFolderBase> tempFolders = new List<InventoryFolderBase>(); 196 List<InventoryFolderBase> tempFolders = new List<InventoryFolderBase>();
208 197
209 foreach (InventoryFolderBase folderBase in folders) 198 foreach (InventoryFolderBase folderBase in folders)
210 { 199 {
211 tempFolders.AddRange(getFolderHierarchy(folderBase.ID, command)); 200 tempFolders.AddRange(getFolderHierarchy(folderBase.ID, cmd));
212 } 201 }
213 if (tempFolders.Count > 0) 202 if (tempFolders.Count > 0)
214 { 203 {
@@ -233,20 +222,19 @@ namespace OpenSim.Data.MSSQL
233 folderName = folderName.Substring(0, 64); 222 folderName = folderName.Substring(0, 64);
234 m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on add"); 223 m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on add");
235 } 224 }
236 225 using (SqlConnection conn = new SqlConnection(m_connectionString))
237 using (AutoClosingSqlCommand command = database.Query(sql)) 226 using (SqlCommand cmd = new SqlCommand(sql, conn))
238 { 227 {
239 command.Parameters.Add(database.CreateParameter("folderID", folder.ID)); 228 cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
240 command.Parameters.Add(database.CreateParameter("agentID", folder.Owner)); 229 cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
241 command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID)); 230 cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
242 command.Parameters.Add(database.CreateParameter("folderName", folderName)); 231 cmd.Parameters.Add(database.CreateParameter("folderName", folderName));
243 command.Parameters.Add(database.CreateParameter("type", folder.Type)); 232 cmd.Parameters.Add(database.CreateParameter("type", folder.Type));
244 command.Parameters.Add(database.CreateParameter("version", folder.Version)); 233 cmd.Parameters.Add(database.CreateParameter("version", folder.Version));
245 234 conn.Open();
246 try 235 try
247 { 236 {
248 //IDbCommand result = database.Query(sql, param); 237 cmd.ExecuteNonQuery();
249 command.ExecuteNonQuery();
250 } 238 }
251 catch (Exception e) 239 catch (Exception e)
252 { 240 {
@@ -275,20 +263,20 @@ namespace OpenSim.Data.MSSQL
275 folderName = folderName.Substring(0, 64); 263 folderName = folderName.Substring(0, 64);
276 m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on update"); 264 m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on update");
277 } 265 }
278 266 using (SqlConnection conn = new SqlConnection(m_connectionString))
279 using (AutoClosingSqlCommand command = database.Query(sql)) 267 using (SqlCommand cmd = new SqlCommand(sql, conn))
280 { 268 {
281 command.Parameters.Add(database.CreateParameter("folderID", folder.ID)); 269 cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
282 command.Parameters.Add(database.CreateParameter("agentID", folder.Owner)); 270 cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
283 command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID)); 271 cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
284 command.Parameters.Add(database.CreateParameter("folderName", folderName)); 272 cmd.Parameters.Add(database.CreateParameter("folderName", folderName));
285 command.Parameters.Add(database.CreateParameter("type", folder.Type)); 273 cmd.Parameters.Add(database.CreateParameter("type", folder.Type));
286 command.Parameters.Add(database.CreateParameter("version", folder.Version)); 274 cmd.Parameters.Add(database.CreateParameter("version", folder.Version));
287 command.Parameters.Add(database.CreateParameter("@keyFolderID", folder.ID)); 275 cmd.Parameters.Add(database.CreateParameter("@keyFolderID", folder.ID));
288 276 conn.Open();
289 try 277 try
290 { 278 {
291 command.ExecuteNonQuery(); 279 cmd.ExecuteNonQuery();
292 } 280 }
293 catch (Exception e) 281 catch (Exception e)
294 { 282 {
@@ -304,14 +292,15 @@ namespace OpenSim.Data.MSSQL
304 public void moveInventoryFolder(InventoryFolderBase folder) 292 public void moveInventoryFolder(InventoryFolderBase folder)
305 { 293 {
306 string sql = @"UPDATE inventoryfolders SET parentFolderID = @parentFolderID WHERE folderID = @folderID"; 294 string sql = @"UPDATE inventoryfolders SET parentFolderID = @parentFolderID WHERE folderID = @folderID";
307 using (IDbCommand command = database.Query(sql)) 295 using (SqlConnection conn = new SqlConnection(m_connectionString))
296 using (SqlCommand cmd = new SqlCommand(sql, conn))
308 { 297 {
309 command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID)); 298 cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
310 command.Parameters.Add(database.CreateParameter("@folderID", folder.ID)); 299 cmd.Parameters.Add(database.CreateParameter("@folderID", folder.ID));
311 300 conn.Open();
312 try 301 try
313 { 302 {
314 command.ExecuteNonQuery(); 303 cmd.ExecuteNonQuery();
315 } 304 }
316 catch (Exception e) 305 catch (Exception e)
317 { 306 {
@@ -326,30 +315,27 @@ namespace OpenSim.Data.MSSQL
326 /// <param name="folderID">Id of folder to delete</param> 315 /// <param name="folderID">Id of folder to delete</param>
327 public void deleteInventoryFolder(UUID folderID) 316 public void deleteInventoryFolder(UUID folderID)
328 { 317 {
329 using (SqlConnection connection = database.DatabaseConnection()) 318 string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
319
320 using (SqlConnection conn = new SqlConnection(m_connectionString))
321 using (SqlCommand cmd = new SqlCommand(sql, conn))
330 { 322 {
331 List<InventoryFolderBase> subFolders; 323 List<InventoryFolderBase> subFolders;
332 using (SqlCommand command = new SqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID", connection)) 324 cmd.Parameters.Add(database.CreateParameter("@parentID", UUID.Zero));
333 { 325 conn.Open();
334 command.Parameters.Add(database.CreateParameter("@parentID", UUID.Zero)); 326 subFolders = getFolderHierarchy(folderID, cmd);
335 327
336 AutoClosingSqlCommand autoCommand = new AutoClosingSqlCommand(command);
337
338 subFolders = getFolderHierarchy(folderID, autoCommand);
339 }
340 328
341 //Delete all sub-folders 329 //Delete all sub-folders
342 foreach (InventoryFolderBase f in subFolders) 330 foreach (InventoryFolderBase f in subFolders)
343 { 331 {
344 DeleteOneFolder(f.ID, connection); 332 DeleteOneFolder(f.ID, conn);
345 DeleteItemsInFolder(f.ID, connection); 333 DeleteItemsInFolder(f.ID, conn);
346 } 334 }
347 335
348 //Delete the actual row 336 //Delete the actual row
349 DeleteOneFolder(folderID, connection); 337 DeleteOneFolder(folderID, conn);
350 DeleteItemsInFolder(folderID, connection); 338 DeleteItemsInFolder(folderID, conn);
351
352 connection.Close();
353 } 339 }
354 } 340 }
355 341
@@ -364,13 +350,15 @@ namespace OpenSim.Data.MSSQL
364 /// <returns>A list containing inventory items</returns> 350 /// <returns>A list containing inventory items</returns>
365 public List<InventoryItemBase> getInventoryInFolder(UUID folderID) 351 public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
366 { 352 {
367 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID")) 353 string sql = "SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID";
354 using (SqlConnection conn = new SqlConnection(m_connectionString))
355 using (SqlCommand cmd = new SqlCommand(sql, conn))
368 { 356 {
369 command.Parameters.Add(database.CreateParameter("parentFolderID", folderID)); 357 cmd.Parameters.Add(database.CreateParameter("parentFolderID", folderID));
370 358 conn.Open();
371 List<InventoryItemBase> items = new List<InventoryItemBase>(); 359 List<InventoryItemBase> items = new List<InventoryItemBase>();
372 360
373 using (SqlDataReader reader = command.ExecuteReader()) 361 using (SqlDataReader reader = cmd.ExecuteReader())
374 { 362 {
375 while (reader.Read()) 363 while (reader.Read())
376 { 364 {
@@ -388,11 +376,13 @@ namespace OpenSim.Data.MSSQL
388 /// <returns>An inventory item</returns> 376 /// <returns>An inventory item</returns>
389 public InventoryItemBase getInventoryItem(UUID itemID) 377 public InventoryItemBase getInventoryItem(UUID itemID)
390 { 378 {
391 using (AutoClosingSqlCommand result = database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID")) 379 string sql = "SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID";
380 using (SqlConnection conn = new SqlConnection(m_connectionString))
381 using (SqlCommand cmd = new SqlCommand(sql, conn))
392 { 382 {
393 result.Parameters.Add(database.CreateParameter("inventoryID", itemID)); 383 cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
394 384 conn.Open();
395 using (IDataReader reader = result.ExecuteReader()) 385 using (SqlDataReader reader = cmd.ExecuteReader())
396 { 386 {
397 if (reader.Read()) 387 if (reader.Read())
398 { 388 {
@@ -441,8 +431,9 @@ namespace OpenSim.Data.MSSQL
441 itemDesc = item.Description.Substring(0, 128); 431 itemDesc = item.Description.Substring(0, 128);
442 m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters"); 432 m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters");
443 } 433 }
444 434
445 using (AutoClosingSqlCommand command = database.Query(sql)) 435 using (SqlConnection conn = new SqlConnection(m_connectionString))
436 using (SqlCommand command = new SqlCommand(sql, conn))
446 { 437 {
447 command.Parameters.Add(database.CreateParameter("inventoryID", item.ID)); 438 command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
448 command.Parameters.Add(database.CreateParameter("assetID", item.AssetID)); 439 command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
@@ -464,7 +455,7 @@ namespace OpenSim.Data.MSSQL
464 command.Parameters.Add(database.CreateParameter("groupID", item.GroupID)); 455 command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
465 command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned)); 456 command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
466 command.Parameters.Add(database.CreateParameter("flags", item.Flags)); 457 command.Parameters.Add(database.CreateParameter("flags", item.Flags));
467 458 conn.Open();
468 try 459 try
469 { 460 {
470 command.ExecuteNonQuery(); 461 command.ExecuteNonQuery();
@@ -476,9 +467,11 @@ namespace OpenSim.Data.MSSQL
476 } 467 }
477 468
478 sql = "UPDATE inventoryfolders SET version = version + 1 WHERE folderID = @folderID"; 469 sql = "UPDATE inventoryfolders SET version = version + 1 WHERE folderID = @folderID";
479 using (AutoClosingSqlCommand command = database.Query(sql)) 470 using (SqlConnection conn = new SqlConnection(m_connectionString))
471 using (SqlCommand command = new SqlCommand(sql, conn))
480 { 472 {
481 command.Parameters.Add(database.CreateParameter("folderID", item.Folder.ToString())); 473 command.Parameters.Add(database.CreateParameter("folderID", item.Folder.ToString()));
474 conn.Open();
482 try 475 try
483 { 476 {
484 command.ExecuteNonQuery(); 477 command.ExecuteNonQuery();
@@ -530,8 +523,9 @@ namespace OpenSim.Data.MSSQL
530 itemDesc = item.Description.Substring(0, 128); 523 itemDesc = item.Description.Substring(0, 128);
531 m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters on update"); 524 m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters on update");
532 } 525 }
533 526
534 using (AutoClosingSqlCommand command = database.Query(sql)) 527 using (SqlConnection conn = new SqlConnection(m_connectionString))
528 using (SqlCommand command = new SqlCommand(sql, conn))
535 { 529 {
536 command.Parameters.Add(database.CreateParameter("inventoryID", item.ID)); 530 command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
537 command.Parameters.Add(database.CreateParameter("assetID", item.AssetID)); 531 command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
@@ -552,8 +546,8 @@ namespace OpenSim.Data.MSSQL
552 command.Parameters.Add(database.CreateParameter("groupID", item.GroupID)); 546 command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
553 command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned)); 547 command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
554 command.Parameters.Add(database.CreateParameter("flags", item.Flags)); 548 command.Parameters.Add(database.CreateParameter("flags", item.Flags));
555 command.Parameters.Add(database.CreateParameter("@keyInventoryID", item.ID)); 549 command.Parameters.Add(database.CreateParameter("keyInventoryID", item.ID));
556 550 conn.Open();
557 try 551 try
558 { 552 {
559 command.ExecuteNonQuery(); 553 command.ExecuteNonQuery();
@@ -573,13 +567,15 @@ namespace OpenSim.Data.MSSQL
573 /// <param name="itemID">the item UUID</param> 567 /// <param name="itemID">the item UUID</param>
574 public void deleteInventoryItem(UUID itemID) 568 public void deleteInventoryItem(UUID itemID)
575 { 569 {
576 using (AutoClosingSqlCommand command = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@inventoryID")) 570 string sql = "DELETE FROM inventoryitems WHERE inventoryID=@inventoryID";
571 using (SqlConnection conn = new SqlConnection(m_connectionString))
572 using (SqlCommand cmd = new SqlCommand(sql, conn))
577 { 573 {
578 command.Parameters.Add(database.CreateParameter("inventoryID", itemID)); 574 cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
579 try 575 try
580 { 576 {
581 577 conn.Open();
582 command.ExecuteNonQuery(); 578 cmd.ExecuteNonQuery();
583 } 579 }
584 catch (Exception e) 580 catch (Exception e)
585 { 581 {
@@ -607,12 +603,14 @@ namespace OpenSim.Data.MSSQL
607 /// </returns> 603 /// </returns>
608 public List<InventoryItemBase> fetchActiveGestures(UUID avatarID) 604 public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
609 { 605 {
610 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryitems WHERE avatarId = @uuid AND assetType = @assetType and flags = 1")) 606 string sql = "SELECT * FROM inventoryitems WHERE avatarId = @uuid AND assetType = @assetType and flags = 1";
611 { 607 using (SqlConnection conn = new SqlConnection(m_connectionString))
612 command.Parameters.Add(database.CreateParameter("uuid", avatarID)); 608 using (SqlCommand cmd = new SqlCommand(sql, conn))
613 command.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture)); 609 {
614 610 cmd.Parameters.Add(database.CreateParameter("uuid", avatarID));
615 using (IDataReader reader = command.ExecuteReader()) 611 cmd.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture));
612 conn.Open();
613 using (SqlDataReader reader = cmd.ExecuteReader())
616 { 614 {
617 List<InventoryItemBase> gestureList = new List<InventoryItemBase>(); 615 List<InventoryItemBase> gestureList = new List<InventoryItemBase>();
618 while (reader.Read()) 616 while (reader.Read())
@@ -656,7 +654,7 @@ namespace OpenSim.Data.MSSQL
656 /// <param name="parentID">parent ID.</param> 654 /// <param name="parentID">parent ID.</param>
657 /// <param name="command">SQL command/connection to database</param> 655 /// <param name="command">SQL command/connection to database</param>
658 /// <returns></returns> 656 /// <returns></returns>
659 private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, AutoClosingSqlCommand command) 657 private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, SqlCommand command)
660 { 658 {
661 command.Parameters["@parentID"].Value = parentID.Guid; //.ToString(); 659 command.Parameters["@parentID"].Value = parentID.Guid; //.ToString();
662 660
@@ -687,7 +685,9 @@ namespace OpenSim.Data.MSSQL
687 /// <returns></returns> 685 /// <returns></returns>
688 private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user) 686 private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user)
689 { 687 {
690 using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid")) 688 string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid";
689 using (SqlConnection conn = new SqlConnection(m_connectionString))
690 using (SqlCommand command = new SqlCommand(sql, conn))
691 { 691 {
692 if (user == UUID.Zero) 692 if (user == UUID.Zero)
693 { 693 {
@@ -698,7 +698,7 @@ namespace OpenSim.Data.MSSQL
698 command.Parameters.Add(database.CreateParameter("uuid", user)); 698 command.Parameters.Add(database.CreateParameter("uuid", user));
699 } 699 }
700 command.Parameters.Add(database.CreateParameter("parentID", parentID)); 700 command.Parameters.Add(database.CreateParameter("parentID", parentID));
701 701 conn.Open();
702 return getInventoryFolders(command); 702 return getInventoryFolders(command);
703 } 703 }
704 } 704 }
@@ -708,9 +708,9 @@ namespace OpenSim.Data.MSSQL
708 /// </summary> 708 /// </summary>
709 /// <param name="command">SQLcommand.</param> 709 /// <param name="command">SQLcommand.</param>
710 /// <returns></returns> 710 /// <returns></returns>
711 private static List<InventoryFolderBase> getInventoryFolders(AutoClosingSqlCommand command) 711 private static List<InventoryFolderBase> getInventoryFolders(SqlCommand command)
712 { 712 {
713 using (IDataReader reader = command.ExecuteReader()) 713 using (SqlDataReader reader = command.ExecuteReader())
714 { 714 {
715 715
716 List<InventoryFolderBase> items = new List<InventoryFolderBase>(); 716 List<InventoryFolderBase> items = new List<InventoryFolderBase>();
@@ -727,7 +727,7 @@ namespace OpenSim.Data.MSSQL
727 /// </summary> 727 /// </summary>
728 /// <param name="reader">A MSSQL Data Reader</param> 728 /// <param name="reader">A MSSQL Data Reader</param>
729 /// <returns>A List containing inventory folders</returns> 729 /// <returns>A List containing inventory folders</returns>
730 protected static InventoryFolderBase readInventoryFolder(IDataReader reader) 730 protected static InventoryFolderBase readInventoryFolder(SqlDataReader reader)
731 { 731 {
732 try 732 try
733 { 733 {
diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
index 0b430c7..d6cb91f 100644
--- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
@@ -54,28 +54,16 @@ namespace OpenSim.Data.MSSQL
54 /// The database manager 54 /// The database manager
55 /// </summary> 55 /// </summary>
56 private MSSQLManager _Database; 56 private MSSQLManager _Database;
57 57 private string m_connectionString;
58 /// <summary> 58 /// <summary>
59 /// Initialises the region datastore 59 /// Initialises the region datastore
60 /// </summary> 60 /// </summary>
61 /// <param name="connectionString">The connection string.</param> 61 /// <param name="connectionString">The connection string.</param>
62 public void Initialise(string connectionString) 62 public void Initialise(string connectionString)
63 { 63 {
64 if (!string.IsNullOrEmpty(connectionString)) 64 m_connectionString = connectionString;
65 { 65 _Database = new MSSQLManager(connectionString);
66 _Database = new MSSQLManager(connectionString); 66
67 }
68 else
69 {
70 IniFile iniFile = new IniFile("mssql_connection.ini");
71 string settingDataSource = iniFile.ParseFileReadValue("data_source");
72 string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog");
73 string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info");
74 string settingUserId = iniFile.ParseFileReadValue("user_id");
75 string settingPassword = iniFile.ParseFileReadValue("password");
76
77 _Database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword);
78 }
79 67
80 //Migration settings 68 //Migration settings
81 _Database.CheckMigration(_migrationStore); 69 _Database.CheckMigration(_migrationStore);
@@ -102,17 +90,18 @@ namespace OpenSim.Data.MSSQL
102 SceneObjectGroup grp = null; 90 SceneObjectGroup grp = null;
103 91
104 92
105 string query = "SELECT *, " + 93 string sql = "SELECT *, " +
106 "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " + 94 "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " +
107 "FROM prims " + 95 "FROM prims " +
108 "LEFT JOIN primshapes ON prims.UUID = primshapes.UUID " + 96 "LEFT JOIN primshapes ON prims.UUID = primshapes.UUID " +
109 "WHERE RegionUUID = @RegionUUID " + 97 "WHERE RegionUUID = @RegionUUID " +
110 "ORDER BY SceneGroupID asc, sort asc, LinkNumber asc"; 98 "ORDER BY SceneGroupID asc, sort asc, LinkNumber asc";
111 99
112 using (AutoClosingSqlCommand command = _Database.Query(query)) 100 using (SqlConnection conn = new SqlConnection(m_connectionString))
101 using (SqlCommand command = new SqlCommand(sql, conn))
113 { 102 {
114 command.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); 103 command.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID));
115 104 conn.Open();
116 using (SqlDataReader reader = command.ExecuteReader()) 105 using (SqlDataReader reader = command.ExecuteReader())
117 { 106 {
118 while (reader.Read()) 107 while (reader.Read())
@@ -122,7 +111,7 @@ namespace OpenSim.Data.MSSQL
122 sceneObjectPart.Shape = PrimitiveBaseShape.Default; 111 sceneObjectPart.Shape = PrimitiveBaseShape.Default;
123 else 112 else
124 sceneObjectPart.Shape = BuildShape(reader); 113 sceneObjectPart.Shape = BuildShape(reader);
125 114
126 prims[sceneObjectPart.UUID] = sceneObjectPart; 115 prims[sceneObjectPart.UUID] = sceneObjectPart;
127 116
128 UUID groupID = new UUID((Guid)reader["SceneGroupID"]); 117 UUID groupID = new UUID((Guid)reader["SceneGroupID"]);
@@ -133,7 +122,7 @@ namespace OpenSim.Data.MSSQL
133 objects[grp.UUID] = grp; 122 objects[grp.UUID] = grp;
134 123
135 lastGroupID = groupID; 124 lastGroupID = groupID;
136 125
137 // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are 126 // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are
138 // recorded as the root prim (for which the UUID must equal the persisted group UUID). In 127 // recorded as the root prim (for which the UUID must equal the persisted group UUID). In
139 // this case, force the UUID to be the same as the group UUID so that at least these can be 128 // this case, force the UUID to be the same as the group UUID so that at least these can be
@@ -142,7 +131,7 @@ namespace OpenSim.Data.MSSQL
142 if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero) 131 if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero)
143 { 132 {
144 _Log.WarnFormat( 133 _Log.WarnFormat(
145 "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", 134 "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID",
146 sceneObjectPart.Name, sceneObjectPart.UUID, sceneObjectPart.GroupPosition, groupID); 135 sceneObjectPart.Name, sceneObjectPart.UUID, sceneObjectPart.GroupPosition, groupID);
147 136
148 sceneObjectPart.UUID = groupID; 137 sceneObjectPart.UUID = groupID;
@@ -174,8 +163,10 @@ namespace OpenSim.Data.MSSQL
174 // LoadItems only on those 163 // LoadItems only on those
175 List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>(); 164 List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>();
176 string qry = "select distinct primID from primitems"; 165 string qry = "select distinct primID from primitems";
177 using (AutoClosingSqlCommand command = _Database.Query(qry)) 166 using (SqlConnection conn = new SqlConnection(m_connectionString))
167 using (SqlCommand command = new SqlCommand(qry, conn))
178 { 168 {
169 conn.Open();
179 using (SqlDataReader itemReader = command.ExecuteReader()) 170 using (SqlDataReader itemReader = command.ExecuteReader())
180 { 171 {
181 while (itemReader.Read()) 172 while (itemReader.Read())
@@ -205,14 +196,16 @@ namespace OpenSim.Data.MSSQL
205 /// <param name="allPrims">all prims with inventory on a region</param> 196 /// <param name="allPrims">all prims with inventory on a region</param>
206 private void LoadItems(List<SceneObjectPart> allPrimsWithInventory) 197 private void LoadItems(List<SceneObjectPart> allPrimsWithInventory)
207 { 198 {
208 199 string sql = "SELECT * FROM primitems WHERE PrimID = @PrimID";
209 using (AutoClosingSqlCommand command = _Database.Query("SELECT * FROM primitems WHERE PrimID = @PrimID")) 200 using (SqlConnection conn = new SqlConnection(m_connectionString))
201 using (SqlCommand command = new SqlCommand(sql, conn))
210 { 202 {
203 conn.Open();
211 foreach (SceneObjectPart objectPart in allPrimsWithInventory) 204 foreach (SceneObjectPart objectPart in allPrimsWithInventory)
212 { 205 {
213 command.Parameters.Clear(); 206 command.Parameters.Clear();
214 command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); 207 command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
215 208
216 List<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); 209 List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
217 210
218 using (SqlDataReader reader = command.ExecuteReader()) 211 using (SqlDataReader reader = command.ExecuteReader())
@@ -241,8 +234,9 @@ namespace OpenSim.Data.MSSQL
241 { 234 {
242 _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); 235 _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
243 236
244 using (SqlConnection conn = _Database.DatabaseConnection()) 237 using (SqlConnection conn = new SqlConnection(m_connectionString))
245 { 238 {
239 conn.Open();
246 SqlTransaction transaction = conn.BeginTransaction(); 240 SqlTransaction transaction = conn.BeginTransaction();
247 241
248 try 242 try
@@ -437,8 +431,12 @@ ELSE
437 lock (_Database) 431 lock (_Database)
438 { 432 {
439 //Using the non transaction mode. 433 //Using the non transaction mode.
440 using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) 434 using (SqlConnection conn = new SqlConnection(m_connectionString))
435 using (SqlCommand cmd = new SqlCommand())
441 { 436 {
437 cmd.Connection = conn;
438 cmd.CommandText = sqlPrimShapes;
439 conn.Open();
442 cmd.Parameters.Add(_Database.CreateParameter("objectID", objectID)); 440 cmd.Parameters.Add(_Database.CreateParameter("objectID", objectID));
443 cmd.ExecuteNonQuery(); 441 cmd.ExecuteNonQuery();
444 442
@@ -466,24 +464,30 @@ ELSE
466 464
467 //Delete everything from PrimID 465 //Delete everything from PrimID
468 //TODO add index on PrimID in DB, if not already exist 466 //TODO add index on PrimID in DB, if not already exist
469 using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) 467
468 string sql = "DELETE PRIMITEMS WHERE primID = @primID";
469 using (SqlConnection conn = new SqlConnection(m_connectionString))
470 using (SqlCommand cmd = new SqlCommand(sql, conn))
470 { 471 {
471 cmd.Parameters.Add(_Database.CreateParameter("@primID", primID)); 472 cmd.Parameters.Add(_Database.CreateParameter("@primID", primID));
473 conn.Open();
472 cmd.ExecuteNonQuery(); 474 cmd.ExecuteNonQuery();
473 } 475 }
474 476
475 string sql = 477 sql =
476 @"INSERT INTO primitems ( 478 @"INSERT INTO primitems (
477 itemID,primID,assetID,parentFolderID,invType,assetType,name,description,creationDate,creatorID,ownerID,lastOwnerID,groupID, 479 itemID,primID,assetID,parentFolderID,invType,assetType,name,description,creationDate,creatorID,ownerID,lastOwnerID,groupID,
478 nextPermissions,currentPermissions,basePermissions,everyonePermissions,groupPermissions,flags) 480 nextPermissions,currentPermissions,basePermissions,everyonePermissions,groupPermissions,flags)
479 VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID, 481 VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID,
480 @lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; 482 @lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)";
481 483
482 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 484 using (SqlConnection conn = new SqlConnection(m_connectionString))
485 using (SqlCommand cmd = new SqlCommand(sql, conn))
483 { 486 {
484 foreach (TaskInventoryItem taskItem in items) 487 foreach (TaskInventoryItem taskItem in items)
485 { 488 {
486 cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem)); 489 cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem));
490 conn.Open();
487 cmd.ExecuteNonQuery(); 491 cmd.ExecuteNonQuery();
488 492
489 cmd.Parameters.Clear(); 493 cmd.Parameters.Clear();
@@ -505,11 +509,12 @@ ELSE
505 509
506 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; 510 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
507 511
508 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 512 using (SqlConnection conn = new SqlConnection(m_connectionString))
513 using (SqlCommand cmd = new SqlCommand(sql, conn))
509 { 514 {
510 // MySqlParameter param = new MySqlParameter(); 515 // MySqlParameter param = new MySqlParameter();
511 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); 516 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
512 517 conn.Open();
513 using (SqlDataReader reader = cmd.ExecuteReader()) 518 using (SqlDataReader reader = cmd.ExecuteReader())
514 { 519 {
515 int rev; 520 int rev;
@@ -549,19 +554,23 @@ ELSE
549 554
550 //Delete old terrain map 555 //Delete old terrain map
551 string sql = "delete from terrain where RegionUUID=@RegionUUID"; 556 string sql = "delete from terrain where RegionUUID=@RegionUUID";
552 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 557 using (SqlConnection conn = new SqlConnection(m_connectionString))
558 using (SqlCommand cmd = new SqlCommand(sql, conn))
553 { 559 {
554 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); 560 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
561 conn.Open();
555 cmd.ExecuteNonQuery(); 562 cmd.ExecuteNonQuery();
556 } 563 }
557 564
558 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; 565 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";
559 566
560 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 567 using (SqlConnection conn = new SqlConnection(m_connectionString))
568 using (SqlCommand cmd = new SqlCommand(sql, conn))
561 { 569 {
562 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); 570 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
563 cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); 571 cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision));
564 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); 572 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain)));
573 conn.Open();
565 cmd.ExecuteNonQuery(); 574 cmd.ExecuteNonQuery();
566 } 575 }
567 576
@@ -580,11 +589,12 @@ ELSE
580 string sql = "select * from land where RegionUUID = @RegionUUID"; 589 string sql = "select * from land where RegionUUID = @RegionUUID";
581 590
582 //Retrieve all land data from region 591 //Retrieve all land data from region
583 using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) 592 using (SqlConnection conn = new SqlConnection(m_connectionString))
593 using (SqlCommand cmd = new SqlCommand(sql, conn))
584 { 594 {
585 cmdLandData.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID)); 595 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID));
586 596 conn.Open();
587 using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) 597 using (SqlDataReader readerLandData = cmd.ExecuteReader())
588 { 598 {
589 while (readerLandData.Read()) 599 while (readerLandData.Read())
590 { 600 {
@@ -597,10 +607,12 @@ ELSE
597 foreach (LandData LandData in LandDataForRegion) 607 foreach (LandData LandData in LandDataForRegion)
598 { 608 {
599 sql = "select * from landaccesslist where LandUUID = @LandUUID"; 609 sql = "select * from landaccesslist where LandUUID = @LandUUID";
600 using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) 610 using (SqlConnection conn = new SqlConnection(m_connectionString))
611 using (SqlCommand cmd = new SqlCommand(sql, conn))
601 { 612 {
602 cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", LandData.GlobalID)); 613 cmd.Parameters.Add(_Database.CreateParameter("@LandUUID", LandData.GlobalID));
603 using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) 614 conn.Open();
615 using (SqlDataReader readerAccessList = cmd.ExecuteReader())
604 { 616 {
605 while (readerAccessList.Read()) 617 while (readerAccessList.Read())
606 { 618 {
@@ -632,17 +644,20 @@ ELSE
632VALUES 644VALUES
633(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)"; 645(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)";
634 646
635 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 647 using (SqlConnection conn = new SqlConnection(m_connectionString))
648 using (SqlCommand cmd = new SqlCommand(sql, conn))
636 { 649 {
637 cmd.Parameters.AddRange(CreateLandParameters(parcel.LandData, parcel.RegionUUID)); 650 cmd.Parameters.AddRange(CreateLandParameters(parcel.LandData, parcel.RegionUUID));
638 651 conn.Open();
639 cmd.ExecuteNonQuery(); 652 cmd.ExecuteNonQuery();
640 } 653 }
641 654
642 sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; 655 sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)";
643 656
644 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 657 using (SqlConnection conn = new SqlConnection(m_connectionString))
658 using (SqlCommand cmd = new SqlCommand(sql, conn))
645 { 659 {
660 conn.Open();
646 foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.LandData.ParcelAccessList) 661 foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.LandData.ParcelAccessList)
647 { 662 {
648 cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.RegionUUID)); 663 cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.RegionUUID));
@@ -659,25 +674,30 @@ VALUES
659 /// <param name="globalID">UUID of landobject</param> 674 /// <param name="globalID">UUID of landobject</param>
660 public void RemoveLandObject(UUID globalID) 675 public void RemoveLandObject(UUID globalID)
661 { 676 {
662 using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) 677 string sql = "delete from land where UUID=@UUID";
678 using (SqlConnection conn = new SqlConnection(m_connectionString))
679 using (SqlCommand cmd = new SqlCommand(sql, conn))
663 { 680 {
664 cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); 681 cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID));
682 conn.Open();
665 cmd.ExecuteNonQuery(); 683 cmd.ExecuteNonQuery();
666 } 684 }
667 685 sql = "delete from landaccesslist where LandUUID=@UUID";
668 using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) 686 using (SqlConnection conn = new SqlConnection(m_connectionString))
687 using (SqlCommand cmd = new SqlCommand(sql, conn))
669 { 688 {
670 cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); 689 cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID));
690 conn.Open();
671 cmd.ExecuteNonQuery(); 691 cmd.ExecuteNonQuery();
672 } 692 }
673 } 693 }
674 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) 694 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
675 { 695 {
676 //This connector doesn't support the windlight module yet 696 //This connector doesn't support the windlight module yet
677 //Return default LL windlight settings 697 //Return default LL windlight settings
678 return new RegionMeta7WindlightData(); 698 return new RegionLightShareData();
679 } 699 }
680 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) 700 public void StoreRegionWindlightSettings(RegionLightShareData wl)
681 { 701 {
682 //This connector doesn't support the windlight module yet 702 //This connector doesn't support the windlight module yet
683 } 703 }
@@ -690,9 +710,11 @@ VALUES
690 { 710 {
691 string sql = "select * from regionsettings where regionUUID = @regionUUID"; 711 string sql = "select * from regionsettings where regionUUID = @regionUUID";
692 RegionSettings regionSettings; 712 RegionSettings regionSettings;
693 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 713 using (SqlConnection conn = new SqlConnection(m_connectionString))
714 using (SqlCommand cmd = new SqlCommand(sql, conn))
694 { 715 {
695 cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); 716 cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID));
717 conn.Open();
696 using (SqlDataReader reader = cmd.ExecuteReader()) 718 using (SqlDataReader reader = cmd.ExecuteReader())
697 { 719 {
698 if (reader.Read()) 720 if (reader.Read())
@@ -724,9 +746,12 @@ VALUES
724 { 746 {
725 //Little check if regionUUID already exist in DB 747 //Little check if regionUUID already exist in DB
726 string regionUUID; 748 string regionUUID;
727 using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) 749 string sql = "SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID";
750 using (SqlConnection conn = new SqlConnection(m_connectionString))
751 using (SqlCommand cmd = new SqlCommand(sql, conn))
728 { 752 {
729 cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID)); 753 cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID));
754 conn.Open();
730 regionUUID = cmd.ExecuteScalar().ToString(); 755 regionUUID = cmd.ExecuteScalar().ToString();
731 } 756 }
732 757
@@ -737,8 +762,8 @@ VALUES
737 else 762 else
738 { 763 {
739 //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB 764 //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB
740 string sql = 765 sql =
741 @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage 766 @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage
742,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide 767,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide
743,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity 768,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity
744,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics 769,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics
@@ -750,10 +775,11 @@ VALUES
750,[covenant] = @covenant , [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id 775,[covenant] = @covenant , [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id
751 WHERE [regionUUID] = @regionUUID"; 776 WHERE [regionUUID] = @regionUUID";
752 777
753 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 778 using (SqlConnection conn = new SqlConnection(m_connectionString))
779 using (SqlCommand cmd = new SqlCommand(sql, conn))
754 { 780 {
755 cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); 781 cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings));
756 782 conn.Open();
757 cmd.ExecuteNonQuery(); 783 cmd.ExecuteNonQuery();
758 } 784 }
759 } 785 }
@@ -810,9 +836,11 @@ VALUES
810 @elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit, 836 @elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit,
811 @terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@sunvectorx,@sunvectory, @sunvectorz, @Sandbox, @loaded_creation_datetime, @loaded_creation_id)"; 837 @terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@sunvectorx,@sunvectory, @sunvectorz, @Sandbox, @loaded_creation_datetime, @loaded_creation_id)";
812 838
813 using (AutoClosingSqlCommand cmd = _Database.Query(sql)) 839 using (SqlConnection conn = new SqlConnection(m_connectionString))
840 using (SqlCommand cmd = new SqlCommand(sql, conn))
814 { 841 {
815 cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); 842 cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings));
843 conn.Open();
816 cmd.ExecuteNonQuery(); 844 cmd.ExecuteNonQuery();
817 } 845 }
818 } 846 }
@@ -916,15 +944,15 @@ VALUES
916 newData.PassHours = Convert.ToSingle(row["PassHours"]); 944 newData.PassHours = Convert.ToSingle(row["PassHours"]);
917 newData.PassPrice = Convert.ToInt32(row["PassPrice"]); 945 newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
918 946
919// UUID authedbuyer; 947 // UUID authedbuyer;
920// UUID snapshotID; 948 // UUID snapshotID;
921// 949 //
922// if (UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) 950 // if (UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer))
923// newData.AuthBuyerID = authedbuyer; 951 // newData.AuthBuyerID = authedbuyer;
924// 952 //
925// if (UUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) 953 // if (UUID.TryParse((string)row["SnapshotUUID"], out snapshotID))
926// newData.SnapshotID = snapshotID; 954 // newData.SnapshotID = snapshotID;
927 newData.AuthBuyerID = new UUID((Guid) row["AuthBuyerID"]); 955 newData.AuthBuyerID = new UUID((Guid)row["AuthBuyerID"]);
928 newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); 956 newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]);
929 957
930 newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); 958 newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
@@ -1193,7 +1221,7 @@ VALUES
1193 #endregion 1221 #endregion
1194 1222
1195 #region Create parameters methods 1223 #region Create parameters methods
1196 1224
1197 /// <summary> 1225 /// <summary>
1198 /// Creates the prim inventory parameters. 1226 /// Creates the prim inventory parameters.
1199 /// </summary> 1227 /// </summary>
@@ -1477,7 +1505,7 @@ VALUES
1477 1505
1478 parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); 1506 parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound));
1479 parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); 1507 parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume));
1480 if (prim.PassTouches) 1508 if (prim.PassTouches)
1481 parameters.Add(_Database.CreateParameter("PassTouches", 1)); 1509 parameters.Add(_Database.CreateParameter("PassTouches", 1));
1482 else 1510 else
1483 parameters.Add(_Database.CreateParameter("PassTouches", 0)); 1511 parameters.Add(_Database.CreateParameter("PassTouches", 0));
@@ -1532,7 +1560,7 @@ VALUES
1532 1560
1533 return parameters.ToArray(); 1561 return parameters.ToArray();
1534 } 1562 }
1535 1563
1536 #endregion 1564 #endregion
1537 1565
1538 #endregion 1566 #endregion
diff --git a/OpenSim/Data/MSSQL/MSSQLLogData.cs b/OpenSim/Data/MSSQL/MSSQLLogData.cs
deleted file mode 100644
index 72c50e6..0000000
--- a/OpenSim/Data/MSSQL/MSSQLLogData.cs
+++ /dev/null
@@ -1,146 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using log4net;
31using OpenSim.Framework;
32
33namespace OpenSim.Data.MSSQL
34{
35 /// <summary>
36 /// An interface to the log database for MSSQL
37 /// </summary>
38 internal class MSSQLLogData : ILogDataPlugin
39 {
40 private const string _migrationStore = "LogStore";
41
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 /// <summary>
45 /// The database manager
46 /// </summary>
47 public MSSQLManager database;
48
49 [Obsolete("Cannot be default-initialized!")]
50 public void Initialise()
51 {
52 m_log.Info("[LOG DB]: " + Name + " cannot be default-initialized!");
53 throw new PluginNotInitialisedException (Name);
54 }
55
56 /// <summary>
57 /// Artificial constructor called when the plugin is loaded
58 /// </summary>
59 public void Initialise(string connect)
60 {
61 if (!string.IsNullOrEmpty(connect))
62 {
63 database = new MSSQLManager(connect);
64 }
65 else
66 {
67 // TODO: do something with the connect string
68 IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini");
69 string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source");
70 string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog");
71 string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info");
72 string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id");
73 string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password");
74
75 database =
76 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
77 settingPassword);
78 }
79
80 //Updating mechanisme
81 database.CheckMigration(_migrationStore);
82 }
83
84 /// <summary>
85 /// Saves a log item to the database
86 /// </summary>
87 /// <param name="serverDaemon">The daemon triggering the event</param>
88 /// <param name="target">The target of the action (region / agent UUID, etc)</param>
89 /// <param name="methodCall">The method call where the problem occured</param>
90 /// <param name="arguments">The arguments passed to the method</param>
91 /// <param name="priority">How critical is this?</param>
92 /// <param name="logMessage">The message to log</param>
93 public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,
94 string logMessage)
95 {
96 string sql = "INSERT INTO logs ([target], [server], [method], [arguments], [priority], [message]) VALUES ";
97 sql += "(@target, @server, @method, @arguments, @priority, @message);";
98
99 using (AutoClosingSqlCommand command = database.Query(sql))
100 {
101 command.Parameters.Add(database.CreateParameter("server", serverDaemon));
102 command.Parameters.Add(database.CreateParameter("target",target));
103 command.Parameters.Add(database.CreateParameter("method", methodCall));
104 command.Parameters.Add(database.CreateParameter("arguments", arguments));
105 command.Parameters.Add(database.CreateParameter("priority", priority.ToString()));
106 command.Parameters.Add(database.CreateParameter("message", logMessage));
107
108 try
109 {
110 command.ExecuteNonQuery();
111 }
112 catch (Exception e)
113 {
114 //Are we not in a loop here
115 m_log.Error("[LOG DB] Error logging : " + e.Message);
116 }
117 }
118 }
119
120 /// <summary>
121 /// Returns the name of this DB provider
122 /// </summary>
123 /// <returns>A string containing the DB provider name</returns>
124 public string Name
125 {
126 get { return "MSSQL Logdata Interface"; }
127 }
128
129 /// <summary>
130 /// Closes the database provider
131 /// </summary>
132 public void Dispose()
133 {
134 database = null;
135 }
136
137 /// <summary>
138 /// Returns the version of this DB provider
139 /// </summary>
140 /// <returns>A string containing the provider version</returns>
141 public string Version
142 {
143 get { return "0.1"; }
144 }
145 }
146}
diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs
index 3d7a768..575fd21 100644
--- a/OpenSim/Data/MSSQL/MSSQLManager.cs
+++ b/OpenSim/Data/MSSQL/MSSQLManager.cs
@@ -48,21 +48,6 @@ namespace OpenSim.Data.MSSQL
48 /// </summary> 48 /// </summary>
49 private readonly string connectionString; 49 private readonly string connectionString;
50 50
51 public MSSQLManager(string dataSource, string initialCatalog, string persistSecurityInfo, string userId,
52 string password)
53 {
54 SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
55
56 builder.DataSource = dataSource;
57 builder.InitialCatalog = initialCatalog;
58 builder.PersistSecurityInfo = Convert.ToBoolean(persistSecurityInfo);
59 builder.UserID = userId;
60 builder.Password = password;
61 builder.ApplicationName = Assembly.GetEntryAssembly().Location;
62
63 connectionString = builder.ToString();
64 }
65
66 /// <summary> 51 /// <summary>
67 /// Initialize the manager and set the connectionstring 52 /// Initialize the manager and set the connectionstring
68 /// </summary> 53 /// </summary>
@@ -72,94 +57,6 @@ namespace OpenSim.Data.MSSQL
72 connectionString = connection; 57 connectionString = connection;
73 } 58 }
74 59
75 public SqlConnection DatabaseConnection()
76 {
77 SqlConnection conn = new SqlConnection(connectionString);
78
79 //TODO is this good??? Opening connection here
80 conn.Open();
81
82 return conn;
83 }
84
85 #region Obsolete functions, can be removed!
86
87 /// <summary>
88 ///
89 /// </summary>
90 /// <param name="dt"></param>
91 /// <param name="name"></param>
92 /// <param name="type"></param>
93 [Obsolete("Do not use!")]
94 protected static void createCol(DataTable dt, string name, Type type)
95 {
96 DataColumn col = new DataColumn(name, type);
97 dt.Columns.Add(col);
98 }
99
100 /// <summary>
101 /// Define Table function
102 /// </summary>
103 /// <param name="dt"></param>
104 /// <returns></returns>
105/*
106 [Obsolete("Do not use!")]
107 protected static string defineTable(DataTable dt)
108 {
109 string sql = "create table " + dt.TableName + "(";
110 string subsql = String.Empty;
111 foreach (DataColumn col in dt.Columns)
112 {
113 if (subsql.Length > 0)
114 {
115 // a map function would rock so much here
116 subsql += ",\n";
117 }
118
119 subsql += col.ColumnName + " " + SqlType(col.DataType);
120 if (col == dt.PrimaryKey[0])
121 {
122 subsql += " primary key";
123 }
124 }
125 sql += subsql;
126 sql += ")";
127 return sql;
128 }
129*/
130
131 #endregion
132
133 /// <summary>
134 /// Type conversion function
135 /// </summary>
136 /// <param name="type">a type</param>
137 /// <returns>a sqltype</returns>
138 /// <remarks>this is something we'll need to implement for each db slightly differently.</remarks>
139/*
140 [Obsolete("Used by a obsolete methods")]
141 public static string SqlType(Type type)
142 {
143 if (type == typeof(String))
144 {
145 return "varchar(255)";
146 }
147 if (type == typeof(Int32))
148 {
149 return "integer";
150 }
151 if (type == typeof(Double))
152 {
153 return "float";
154 }
155 if (type == typeof(Byte[]))
156 {
157 return "image";
158 }
159 return "varchar(255)";
160 }
161*/
162
163 /// <summary> 60 /// <summary>
164 /// Type conversion to a SQLDbType functions 61 /// Type conversion to a SQLDbType functions
165 /// </summary> 62 /// </summary>
@@ -286,135 +183,21 @@ namespace OpenSim.Data.MSSQL
286 private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>(); 183 private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>();
287 184
288 /// <summary> 185 /// <summary>
289 /// Run a query and return a sql db command
290 /// </summary>
291 /// <param name="sql">The SQL query.</param>
292 /// <returns></returns>
293 internal AutoClosingSqlCommand Query(string sql)
294 {
295 return Query(sql, emptyDictionary);
296 }
297
298 /// <summary>
299 /// Runs a query with protection against SQL Injection by using parameterised input.
300 /// </summary>
301 /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
302 /// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
303 /// <returns>A Sql DB Command</returns>
304 internal AutoClosingSqlCommand Query(string sql, Dictionary<string, string> parameters)
305 {
306 SqlCommand dbcommand = DatabaseConnection().CreateCommand();
307 dbcommand.CommandText = sql;
308 foreach (KeyValuePair<string, string> param in parameters)
309 {
310 dbcommand.Parameters.AddWithValue(param.Key, param.Value);
311 }
312
313 return new AutoClosingSqlCommand(dbcommand);
314 }
315
316 /// <summary>
317 /// Runs a query with protection against SQL Injection by using parameterised input.
318 /// </summary>
319 /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
320 /// <param name="sqlParameter">A parameter - use createparameter to create parameter</param>
321 /// <returns></returns>
322 internal AutoClosingSqlCommand Query(string sql, SqlParameter sqlParameter)
323 {
324 SqlCommand dbcommand = DatabaseConnection().CreateCommand();
325 dbcommand.CommandText = sql;
326 dbcommand.Parameters.Add(sqlParameter);
327
328 return new AutoClosingSqlCommand(dbcommand);
329 }
330
331 /// <summary>
332 /// Checks if we need to do some migrations to the database 186 /// Checks if we need to do some migrations to the database
333 /// </summary> 187 /// </summary>
334 /// <param name="migrationStore">migrationStore.</param> 188 /// <param name="migrationStore">migrationStore.</param>
335 public void CheckMigration(string migrationStore) 189 public void CheckMigration(string migrationStore)
336 { 190 {
337 using (SqlConnection connection = DatabaseConnection()) 191 using (SqlConnection connection = new SqlConnection(connectionString))
338 { 192 {
193 connection.Open();
339 Assembly assem = GetType().Assembly; 194 Assembly assem = GetType().Assembly;
340 MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore); 195 MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore);
341 196
342 migration.Update(); 197 migration.Update();
343
344 connection.Close();
345 } 198 }
346 } 199 }
347 200
348 #region Old Testtable functions
349
350 /// <summary>
351 /// Execute a SQL statement stored in a resource, as a string
352 /// </summary>
353 /// <param name="name">the ressource string</param>
354 public void ExecuteResourceSql(string name)
355 {
356 using (IDbCommand cmd = Query(getResourceString(name), new Dictionary<string, string>()))
357 {
358 cmd.ExecuteNonQuery();
359 }
360 }
361
362 /// <summary>
363 /// Given a list of tables, return the version of the tables, as seen in the database
364 /// </summary>
365 /// <param name="tableList"></param>
366 public void GetTableVersion(Dictionary<string, string> tableList)
367 {
368 Dictionary<string, string> param = new Dictionary<string, string>();
369 param["dbname"] = new SqlConnectionStringBuilder(connectionString).InitialCatalog;
370
371 using (IDbCommand tablesCmd =
372 Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG=@dbname", param))
373 using (IDataReader tables = tablesCmd.ExecuteReader())
374 {
375 while (tables.Read())
376 {
377 try
378 {
379 string tableName = (string)tables["TABLE_NAME"];
380 if (tableList.ContainsKey(tableName))
381 tableList[tableName] = tableName;
382 }
383 catch (Exception e)
384 {
385 m_log.Error(e.ToString());
386 }
387 }
388 tables.Close();
389 }
390
391 }
392
393 /// <summary>
394 ///
395 /// </summary>
396 /// <param name="name"></param>
397 /// <returns></returns>
398 private string getResourceString(string name)
399 {
400 Assembly assem = GetType().Assembly;
401 string[] names = assem.GetManifestResourceNames();
402
403 foreach (string s in names)
404 if (s.EndsWith(name))
405 using (Stream resource = assem.GetManifestResourceStream(s))
406 {
407 using (StreamReader resourceReader = new StreamReader(resource))
408 {
409 string resourceString = resourceReader.ReadToEnd();
410 return resourceString;
411 }
412 }
413 throw new Exception(string.Format("Resource '{0}' was not found", name));
414 }
415
416 #endregion
417
418 /// <summary> 201 /// <summary>
419 /// Returns the version of this DB provider 202 /// Returns the version of this DB provider
420 /// </summary> 203 /// </summary>
diff --git a/OpenSim/Data/MSSQL/MSSQLPresenceData.cs b/OpenSim/Data/MSSQL/MSSQLPresenceData.cs
new file mode 100644
index 0000000..5a4ad3a
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLPresenceData.cs
@@ -0,0 +1,170 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using System.Data.SqlClient;
37
38namespace OpenSim.Data.MSSQL
39{
40 /// <summary>
41 /// A MySQL Interface for the Presence Server
42 /// </summary>
43 public class MSSQLPresenceData : MSSQLGenericTableHandler<PresenceData>,
44 IPresenceData
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public MSSQLPresenceData(string connectionString, string realm) :
49 base(connectionString, realm, "Presence")
50 {
51 }
52
53 public PresenceData Get(UUID sessionID)
54 {
55 PresenceData[] ret = Get("SessionID",
56 sessionID.ToString());
57
58 if (ret.Length == 0)
59 return null;
60
61 return ret[0];
62 }
63
64 public void LogoutRegionAgents(UUID regionID)
65 {
66 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
67 using (SqlCommand cmd = new SqlCommand())
68 {
69
70 cmd.CommandText = String.Format("UPDATE {0} SET Online='false' WHERE [RegionID]=@RegionID", m_Realm);
71
72 cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
73 cmd.Connection = conn;
74 conn.Open();
75 cmd.ExecuteNonQuery();
76 }
77 }
78
79 public bool ReportAgent(UUID sessionID, UUID regionID, string position,
80 string lookAt)
81 {
82 PresenceData[] pd = Get("SessionID", sessionID.ToString());
83 if (pd.Length == 0)
84 return false;
85
86 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
87 using (SqlCommand cmd = new SqlCommand())
88 {
89
90 cmd.CommandText = String.Format(@"UPDATE {0} SET
91 [RegionID] = @RegionID,
92 [Position] = @Position,
93 [LookAt] = @LookAt,
94 [Online] = 'true'
95 WHERE [SessionID] = @SessionID", m_Realm);
96
97 cmd.Parameters.Add(m_database.CreateParameter("@SessionID", sessionID.ToString()));
98 cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
99 cmd.Parameters.Add(m_database.CreateParameter("@Position", position.ToString()));
100 cmd.Parameters.Add(m_database.CreateParameter("@LookAt", lookAt.ToString()));
101 cmd.Connection = conn;
102 conn.Open();
103 if (cmd.ExecuteNonQuery() == 0)
104 return false;
105 }
106 return true;
107 }
108
109 public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
110 {
111 PresenceData[] pd = Get("UserID", userID);
112 if (pd.Length == 0)
113 return false;
114
115 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
116 using (SqlCommand cmd = new SqlCommand())
117 {
118
119 cmd.CommandText = String.Format(@"UPDATE {0} SET
120 [HomeRegionID] = @HomeRegionID,
121 [HomePosition] = @HomePosition,
122 [HomeLookAt] = @HomeLookAt
123 WHERE [UserID] = @UserID", m_Realm);
124
125 cmd.Parameters.Add(m_database.CreateParameter("@UserID", userID));
126 cmd.Parameters.Add(m_database.CreateParameter("@HomeRegionID", regionID.ToString()));
127 cmd.Parameters.Add(m_database.CreateParameter("@HomePosition", position));
128 cmd.Parameters.Add(m_database.CreateParameter("@HomeLookAt", lookAt));
129 cmd.Connection = conn;
130 conn.Open();
131 if (cmd.ExecuteNonQuery() == 0)
132 return false;
133 }
134 return true;
135 }
136
137 public void Prune(string userID)
138 {
139 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
140 using (SqlCommand cmd = new SqlCommand())
141 {
142 cmd.CommandText = String.Format("SELECT * from {0} WHERE [UserID] = @UserID", m_Realm);
143
144 cmd.Parameters.Add(m_database.CreateParameter("@UserID", userID));
145 cmd.Connection = conn;
146 conn.Open();
147
148 using (SqlDataReader reader = cmd.ExecuteReader())
149 {
150 List<UUID> deleteSessions = new List<UUID>();
151 int online = 0;
152
153 while (reader.Read())
154 {
155 if (bool.Parse(reader["Online"].ToString()))
156 online++;
157 else
158 deleteSessions.Add(new UUID(reader["SessionID"].ToString()));
159 }
160
161 if (online == 0 && deleteSessions.Count > 0)
162 deleteSessions.RemoveAt(0);
163
164 foreach (UUID s in deleteSessions)
165 Delete("SessionID", s.ToString());
166 }
167 }
168 }
169 }
170}
diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs
index a898aab..66c3f81 100644
--- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs
@@ -129,10 +129,10 @@ namespace OpenSim.Data.MSSQL
129 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 129 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
130 using (SqlCommand cmd = new SqlCommand(sql, conn)) 130 using (SqlCommand cmd = new SqlCommand(sql, conn))
131 { 131 {
132 cmd.Parameters.Add(m_database.CreateParameter("@startX", startX.ToString())); 132 cmd.Parameters.Add(m_database.CreateParameter("@startX", startX));
133 cmd.Parameters.Add(m_database.CreateParameter("@startY", startY.ToString())); 133 cmd.Parameters.Add(m_database.CreateParameter("@startY", startY));
134 cmd.Parameters.Add(m_database.CreateParameter("@endX", endX.ToString())); 134 cmd.Parameters.Add(m_database.CreateParameter("@endX", endX));
135 cmd.Parameters.Add(m_database.CreateParameter("@endY", endY.ToString())); 135 cmd.Parameters.Add(m_database.CreateParameter("@endY", endY));
136 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); 136 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
137 conn.Open(); 137 conn.Open();
138 return RunCommand(cmd); 138 return RunCommand(cmd);
@@ -307,5 +307,37 @@ namespace OpenSim.Data.MSSQL
307 } 307 }
308 return false; 308 return false;
309 } 309 }
310
311 public List<RegionData> GetDefaultRegions(UUID scopeID)
312 {
313 string sql = "SELECT * FROM [" + m_Realm + "] WHERE (flags & 1) <> 0";
314 if (scopeID != UUID.Zero)
315 sql += " AND ScopeID = @scopeID";
316
317 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
318 using (SqlCommand cmd = new SqlCommand(sql, conn))
319 {
320 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
321 conn.Open();
322 return RunCommand(cmd);
323 }
324
325 }
326
327 public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
328 {
329 string sql = "SELECT * FROM [" + m_Realm + "] WHERE (flags & 2) <> 0";
330 if (scopeID != UUID.Zero)
331 sql += " AND ScopeID = @scopeID";
332
333 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
334 using (SqlCommand cmd = new SqlCommand(sql, conn))
335 {
336 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
337 conn.Open();
338 // TODO: distance-sort results
339 return RunCommand(cmd);
340 }
341 }
310 } 342 }
311} 343}
diff --git a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs
index 2d92cb1..e7c8dc5 100644
--- a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs
@@ -36,153 +36,207 @@ using System.Text;
36 36
37namespace OpenSim.Data.MSSQL 37namespace OpenSim.Data.MSSQL
38{ 38{
39 public class MSSQLUserAccountData : IUserAccountData 39 public class MSSQLUserAccountData : MSSQLGenericTableHandler<UserAccountData>,IUserAccountData
40 { 40 {
41 private string m_Realm; 41 public MSSQLUserAccountData(string connectionString, string realm) :
42 private List<string> m_ColumnNames = null; 42 base(connectionString, realm, "UserAccount")
43 private string m_ConnectionString;
44 private MSSQLManager m_database;
45
46 public MSSQLUserAccountData(string connectionString, string realm)
47 {
48 m_Realm = realm;
49 m_ConnectionString = connectionString;
50 m_database = new MSSQLManager(connectionString);
51
52 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
53 {
54 conn.Open();
55 Migration m = new Migration(conn, GetType().Assembly, "UserStore");
56 m.Update();
57 }
58 }
59
60 public List<UserAccountData> Query(UUID principalID, UUID scopeID, string query)
61 { 43 {
62 return null;
63 } 44 }
64 45 //private string m_Realm;
65 public UserAccountData Get(UUID principalID, UUID scopeID) 46 //private List<string> m_ColumnNames = null;
47 //private MSSQLManager m_database;
48
49 //public MSSQLUserAccountData(string connectionString, string realm)
50 //{
51 // m_Realm = realm;
52 // m_ConnectionString = connectionString;
53 // m_database = new MSSQLManager(connectionString);
54
55 // using (SqlConnection conn = new SqlConnection(m_ConnectionString))
56 // {
57 // conn.Open();
58 // Migration m = new Migration(conn, GetType().Assembly, "UserStore");
59 // m.Update();
60 // }
61 //}
62
63 //public List<UserAccountData> Query(UUID principalID, UUID scopeID, string query)
64 //{
65 // return null;
66 //}
67
68 //public UserAccountData Get(UUID principalID, UUID scopeID)
69 //{
70 // UserAccountData ret = new UserAccountData();
71 // ret.Data = new Dictionary<string, string>();
72
73 // string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
74 // if (scopeID != UUID.Zero)
75 // sql += " and ScopeID = @scopeID";
76
77 // using (SqlConnection conn = new SqlConnection(m_ConnectionString))
78 // using (SqlCommand cmd = new SqlCommand(sql, conn))
79 // {
80 // cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
81 // cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
82
83 // conn.Open();
84 // using (SqlDataReader result = cmd.ExecuteReader())
85 // {
86 // if (result.Read())
87 // {
88 // ret.PrincipalID = principalID;
89 // UUID scope;
90 // UUID.TryParse(result["ScopeID"].ToString(), out scope);
91 // ret.ScopeID = scope;
92
93 // if (m_ColumnNames == null)
94 // {
95 // m_ColumnNames = new List<string>();
96
97 // DataTable schemaTable = result.GetSchemaTable();
98 // foreach (DataRow row in schemaTable.Rows)
99 // m_ColumnNames.Add(row["ColumnName"].ToString());
100 // }
101
102 // foreach (string s in m_ColumnNames)
103 // {
104 // if (s == "UUID")
105 // continue;
106 // if (s == "ScopeID")
107 // continue;
108
109 // ret.Data[s] = result[s].ToString();
110 // }
111 // return ret;
112 // }
113 // }
114 // }
115 // return null;
116 //}
117
118 //public bool Store(UserAccountData data)
119 //{
120 // if (data.Data.ContainsKey("UUID"))
121 // data.Data.Remove("UUID");
122 // if (data.Data.ContainsKey("ScopeID"))
123 // data.Data.Remove("ScopeID");
124
125 // string[] fields = new List<string>(data.Data.Keys).ToArray();
126
127 // using (SqlConnection conn = new SqlConnection(m_ConnectionString))
128 // using (SqlCommand cmd = new SqlCommand())
129 // {
130 // StringBuilder updateBuilder = new StringBuilder();
131 // updateBuilder.AppendFormat("update {0} set ", m_Realm);
132 // bool first = true;
133 // foreach (string field in fields)
134 // {
135 // if (!first)
136 // updateBuilder.Append(", ");
137 // updateBuilder.AppendFormat("{0} = @{0}", field);
138
139 // first = false;
140 // cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
141 // }
142
143 // updateBuilder.Append(" where UUID = @principalID");
144
145 // if (data.ScopeID != UUID.Zero)
146 // updateBuilder.Append(" and ScopeID = @scopeID");
147
148 // cmd.CommandText = updateBuilder.ToString();
149 // cmd.Connection = conn;
150 // cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
151 // cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID));
152 // conn.Open();
153
154 // if (cmd.ExecuteNonQuery() < 1)
155 // {
156 // StringBuilder insertBuilder = new StringBuilder();
157 // insertBuilder.AppendFormat("insert into {0} (UUID, ScopeID, ", m_Realm);
158 // insertBuilder.Append(String.Join(", ", fields));
159 // insertBuilder.Append(") values (@principalID, @scopeID, @");
160 // insertBuilder.Append(String.Join(", @", fields));
161 // insertBuilder.Append(")");
162
163 // cmd.CommandText = insertBuilder.ToString();
164
165 // if (cmd.ExecuteNonQuery() < 1)
166 // {
167 // return false;
168 // }
169 // }
170 // }
171 // return true;
172 //}
173
174 //public bool Store(UserAccountData data, UUID principalID, string token)
175 //{
176 // return false;
177 //}
178
179 //public bool SetDataItem(UUID principalID, string item, string value)
180 //{
181 // string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
182 // using (SqlConnection conn = new SqlConnection(m_ConnectionString))
183 // using (SqlCommand cmd = new SqlCommand(sql, conn))
184 // {
185 // cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
186 // cmd.Parameters.Add(m_database.CreateParameter("@UUID", principalID));
187
188 // conn.Open();
189
190 // if (cmd.ExecuteNonQuery() > 0)
191 // return true;
192 // }
193 // return false;
194 //}
195
196 //public UserAccountData[] Get(string[] keys, string[] vals)
197 //{
198 // return null;
199 //}
200
201 public UserAccountData[] GetUsers(UUID scopeID, string query)
66 { 202 {
67 UserAccountData ret = new UserAccountData(); 203 string[] words = query.Split(new char[] { ' ' });
68 ret.Data = new Dictionary<string, object>();
69
70 string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
71 if (scopeID != UUID.Zero)
72 sql += " and ScopeID = @scopeID";
73 204
74 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 205 for (int i = 0; i < words.Length; i++)
75 using (SqlCommand cmd = new SqlCommand(sql, conn))
76 { 206 {
77 cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); 207 if (words[i].Length < 3)
78 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
79
80 conn.Open();
81 using (SqlDataReader result = cmd.ExecuteReader())
82 { 208 {
83 if (result.Read()) 209 if (i != words.Length - 1)
84 { 210 Array.Copy(words, i + 1, words, i, words.Length - i - 1);
85 ret.PrincipalID = principalID; 211 Array.Resize(ref words, words.Length - 1);
86 UUID scope;
87 UUID.TryParse(result["ScopeID"].ToString(), out scope);
88 ret.ScopeID = scope;
89
90 if (m_ColumnNames == null)
91 {
92 m_ColumnNames = new List<string>();
93
94 DataTable schemaTable = result.GetSchemaTable();
95 foreach (DataRow row in schemaTable.Rows)
96 m_ColumnNames.Add(row["ColumnName"].ToString());
97 }
98
99 foreach (string s in m_ColumnNames)
100 {
101 if (s == "UUID")
102 continue;
103 if (s == "ScopeID")
104 continue;
105
106 ret.Data[s] = result[s].ToString();
107 }
108 return ret;
109 }
110 } 212 }
111 } 213 }
112 return null;
113 }
114 214
115 public bool Store(UserAccountData data) 215 if (words.Length == 0)
116 { 216 return new UserAccountData[0];
117 if (data.Data.ContainsKey("UUID"))
118 data.Data.Remove("UUID");
119 if (data.Data.ContainsKey("ScopeID"))
120 data.Data.Remove("ScopeID");
121 217
122 string[] fields = new List<string>(data.Data.Keys).ToArray(); 218 if (words.Length > 2)
219 return new UserAccountData[0];
123 220
124 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 221 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
125 using (SqlCommand cmd = new SqlCommand()) 222 using (SqlCommand cmd = new SqlCommand())
126 { 223 {
127 StringBuilder updateBuilder = new StringBuilder(); 224 if (words.Length == 1)
128 updateBuilder.AppendFormat("update {0} set ", m_Realm);
129 bool first = true;
130 foreach (string field in fields)
131 { 225 {
132 if (!first) 226 cmd.CommandText = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm);
133 updateBuilder.Append(", "); 227 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
134 updateBuilder.AppendFormat("{0} = @{0}", field); 228 cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%"));
135
136 first = false;
137 cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
138 } 229 }
139 230 else
140 updateBuilder.Append(" where UUID = @principalID");
141
142 if (data.ScopeID != UUID.Zero)
143 updateBuilder.Append(" and ScopeID = @scopeID");
144
145 cmd.CommandText = updateBuilder.ToString();
146 cmd.Connection = conn;
147 cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
148 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID));
149 conn.Open();
150
151 if (cmd.ExecuteNonQuery() < 1)
152 { 231 {
153 StringBuilder insertBuilder = new StringBuilder(); 232 cmd.CommandText = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm);
154 insertBuilder.AppendFormat("insert into {0} (UUID, ScopeID, ", m_Realm); 233 cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%"));
155 insertBuilder.Append(String.Join(", ", fields)); 234 cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%"));
156 insertBuilder.Append(") values (@principalID, @scopeID, @"); 235 cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
157 insertBuilder.Append(String.Join(", @", fields));
158 insertBuilder.Append(")");
159
160 cmd.CommandText = insertBuilder.ToString();
161
162 if (cmd.ExecuteNonQuery() < 1)
163 {
164 return false;
165 }
166 } 236 }
167 }
168 return true;
169 }
170
171 public bool SetDataItem(UUID principalID, string item, string value)
172 {
173 string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
174 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
175 using (SqlCommand cmd = new SqlCommand(sql, conn))
176 {
177 cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
178 cmd.Parameters.Add(m_database.CreateParameter("@UUID", principalID));
179
180 conn.Open();
181 237
182 if (cmd.ExecuteNonQuery() > 0) 238 return DoQuery(cmd);
183 return true;
184 } 239 }
185 return false;
186 } 240 }
187 } 241 }
188} 242}
diff --git a/OpenSim/Data/MSSQL/MSSQLUserData.cs b/OpenSim/Data/MSSQL/MSSQLUserData.cs
deleted file mode 100644
index 3ef1053..0000000
--- a/OpenSim/Data/MSSQL/MSSQLUserData.cs
+++ /dev/null
@@ -1,1214 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using System.Data.SqlClient;
33using System.Reflection;
34using log4net;
35using OpenMetaverse;
36using OpenSim.Framework;
37
38namespace OpenSim.Data.MSSQL
39{
40 /// <summary>
41 /// A database interface class to a user profile storage system
42 /// </summary>
43 public class MSSQLUserData : UserDataBase
44 {
45 private const string _migrationStore = "UserStore";
46
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 /// <summary>
50 /// Database manager for MSSQL
51 /// </summary>
52 public MSSQLManager database;
53
54 private const string m_agentsTableName = "agents";
55 private const string m_usersTableName = "users";
56 private const string m_userFriendsTableName = "userfriends";
57
58 // [Obsolete("Cannot be default-initialized!")]
59 override public void Initialise()
60 {
61 m_log.Info("[MSSQLUserData]: " + Name + " cannot be default-initialized!");
62 throw new PluginNotInitialisedException(Name);
63 }
64
65 /// <summary>
66 /// Loads and initialises the MSSQL storage plugin
67 /// </summary>
68 /// <param name="connect">connectionstring</param>
69 /// <remarks>use mssql_connection.ini</remarks>
70 override public void Initialise(string connect)
71 {
72 if (!string.IsNullOrEmpty(connect))
73 {
74 database = new MSSQLManager(connect);
75 }
76 else
77 {
78 IniFile iniFile = new IniFile("mssql_connection.ini");
79
80 string settingDataSource = iniFile.ParseFileReadValue("data_source");
81 string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog");
82 string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info");
83 string settingUserId = iniFile.ParseFileReadValue("user_id");
84 string settingPassword = iniFile.ParseFileReadValue("password");
85
86 database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword);
87 }
88
89 //Check migration on DB
90 database.CheckMigration(_migrationStore);
91 }
92
93 /// <summary>
94 /// Releases unmanaged and - optionally - managed resources
95 /// </summary>
96 override public void Dispose() { }
97
98 #region User table methods
99
100 /// <summary>
101 /// Searches the database for a specified user profile by name components
102 /// </summary>
103 /// <param name="user">The first part of the account name</param>
104 /// <param name="last">The second part of the account name</param>
105 /// <returns>A user profile</returns>
106 override public UserProfileData GetUserByName(string user, string last)
107 {
108 string sql = string.Format(@"SELECT * FROM {0}
109 WHERE username = @first AND lastname = @second", m_usersTableName);
110 using (AutoClosingSqlCommand command = database.Query(sql))
111 {
112 command.Parameters.Add(database.CreateParameter("first", user));
113 command.Parameters.Add(database.CreateParameter("second", last));
114 try
115 {
116 using (SqlDataReader reader = command.ExecuteReader())
117 {
118 return ReadUserRow(reader);
119 }
120 }
121 catch (Exception e)
122 {
123 m_log.ErrorFormat("[USER DB] Error getting user profile for {0} {1}: {2}", user, last, e.Message);
124 return null;
125 }
126 }
127 }
128
129 /// <summary>
130 /// See IUserDataPlugin
131 /// </summary>
132 /// <param name="uuid"></param>
133 /// <returns></returns>
134 override public UserProfileData GetUserByUUID(UUID uuid)
135 {
136 string sql = string.Format("SELECT * FROM {0} WHERE UUID = @uuid", m_usersTableName);
137 using (AutoClosingSqlCommand command = database.Query(sql))
138 {
139 command.Parameters.Add(database.CreateParameter("uuid", uuid));
140 try
141 {
142 using (SqlDataReader reader = command.ExecuteReader())
143 {
144 return ReadUserRow(reader);
145 }
146 }
147 catch (Exception e)
148 {
149 m_log.ErrorFormat("[USER DB] Error getting user profile by UUID {0}, error: {1}", uuid, e.Message);
150 return null;
151 }
152 }
153 }
154
155
156 /// <summary>
157 /// Creates a new users profile
158 /// </summary>
159 /// <param name="user">The user profile to create</param>
160 override public void AddNewUserProfile(UserProfileData user)
161 {
162 try
163 {
164 InsertUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
165 user.HomeRegion, user.HomeLocation.X, user.HomeLocation.Y,
166 user.HomeLocation.Z,
167 user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created,
168 user.LastLogin, user.UserInventoryURI, user.UserAssetURI,
169 user.CanDoMask, user.WantDoMask,
170 user.AboutText, user.FirstLifeAboutText, user.Image,
171 user.FirstLifeImage, user.WebLoginKey, user.HomeRegionID,
172 user.GodLevel, user.UserFlags, user.CustomType, user.Partner);
173 }
174 catch (Exception e)
175 {
176 m_log.ErrorFormat("[USER DB] Error adding new profile, error: {0}", e.Message);
177 }
178 }
179
180 /// <summary>
181 /// update a user profile
182 /// </summary>
183 /// <param name="user">the profile to update</param>
184 /// <returns></returns>
185 override public bool UpdateUserProfile(UserProfileData user)
186 {
187 string sql = string.Format(@"UPDATE {0}
188 SET UUID = @uuid,
189 username = @username,
190 lastname = @lastname,
191 email = @email,
192 passwordHash = @passwordHash,
193 passwordSalt = @passwordSalt,
194 homeRegion = @homeRegion,
195 homeLocationX = @homeLocationX,
196 homeLocationY = @homeLocationY,
197 homeLocationZ = @homeLocationZ,
198 homeLookAtX = @homeLookAtX,
199 homeLookAtY = @homeLookAtY,
200 homeLookAtZ = @homeLookAtZ,
201 created = @created,
202 lastLogin = @lastLogin,
203 userInventoryURI = @userInventoryURI,
204 userAssetURI = @userAssetURI,
205 profileCanDoMask = @profileCanDoMask,
206 profileWantDoMask = @profileWantDoMask,
207 profileAboutText = @profileAboutText,
208 profileFirstText = @profileFirstText,
209 profileImage = @profileImage,
210 profileFirstImage = @profileFirstImage,
211 webLoginKey = @webLoginKey,
212 homeRegionID = @homeRegionID,
213 userFlags = @userFlags,
214 godLevel = @godLevel,
215 customType = @customType,
216 partner = @partner WHERE UUID = @keyUUUID;",m_usersTableName);
217 using (AutoClosingSqlCommand command = database.Query(sql))
218 {
219 command.Parameters.Add(database.CreateParameter("uuid", user.ID));
220 command.Parameters.Add(database.CreateParameter("username", user.FirstName));
221 command.Parameters.Add(database.CreateParameter("lastname", user.SurName));
222 command.Parameters.Add(database.CreateParameter("email", user.Email));
223 command.Parameters.Add(database.CreateParameter("passwordHash", user.PasswordHash));
224 command.Parameters.Add(database.CreateParameter("passwordSalt", user.PasswordSalt));
225 command.Parameters.Add(database.CreateParameter("homeRegion", user.HomeRegion));
226 command.Parameters.Add(database.CreateParameter("homeLocationX", user.HomeLocation.X));
227 command.Parameters.Add(database.CreateParameter("homeLocationY", user.HomeLocation.Y));
228 command.Parameters.Add(database.CreateParameter("homeLocationZ", user.HomeLocation.Z));
229 command.Parameters.Add(database.CreateParameter("homeLookAtX", user.HomeLookAt.X));
230 command.Parameters.Add(database.CreateParameter("homeLookAtY", user.HomeLookAt.Y));
231 command.Parameters.Add(database.CreateParameter("homeLookAtZ", user.HomeLookAt.Z));
232 command.Parameters.Add(database.CreateParameter("created", user.Created));
233 command.Parameters.Add(database.CreateParameter("lastLogin", user.LastLogin));
234 command.Parameters.Add(database.CreateParameter("userInventoryURI", user.UserInventoryURI));
235 command.Parameters.Add(database.CreateParameter("userAssetURI", user.UserAssetURI));
236 command.Parameters.Add(database.CreateParameter("profileCanDoMask", user.CanDoMask));
237 command.Parameters.Add(database.CreateParameter("profileWantDoMask", user.WantDoMask));
238 command.Parameters.Add(database.CreateParameter("profileAboutText", user.AboutText));
239 command.Parameters.Add(database.CreateParameter("profileFirstText", user.FirstLifeAboutText));
240 command.Parameters.Add(database.CreateParameter("profileImage", user.Image));
241 command.Parameters.Add(database.CreateParameter("profileFirstImage", user.FirstLifeImage));
242 command.Parameters.Add(database.CreateParameter("webLoginKey", user.WebLoginKey));
243 command.Parameters.Add(database.CreateParameter("homeRegionID", user.HomeRegionID));
244 command.Parameters.Add(database.CreateParameter("userFlags", user.UserFlags));
245 command.Parameters.Add(database.CreateParameter("godLevel", user.GodLevel));
246 command.Parameters.Add(database.CreateParameter("customType", user.CustomType));
247 command.Parameters.Add(database.CreateParameter("partner", user.Partner));
248 command.Parameters.Add(database.CreateParameter("keyUUUID", user.ID));
249
250 try
251 {
252 int affected = command.ExecuteNonQuery();
253 return (affected != 0);
254 }
255 catch (Exception e)
256 {
257 m_log.ErrorFormat("[USER DB] Error updating profile, error: {0}", e.Message);
258 }
259 }
260 return false;
261 }
262
263 #endregion
264
265 #region Agent table methods
266
267 /// <summary>
268 /// Returns a user session searching by name
269 /// </summary>
270 /// <param name="name">The account name</param>
271 /// <returns>The users session</returns>
272 override public UserAgentData GetAgentByName(string name)
273 {
274 return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
275 }
276
277 /// <summary>
278 /// Returns a user session by account name
279 /// </summary>
280 /// <param name="user">First part of the users account name</param>
281 /// <param name="last">Second part of the users account name</param>
282 /// <returns>The users session</returns>
283 override public UserAgentData GetAgentByName(string user, string last)
284 {
285 UserProfileData profile = GetUserByName(user, last);
286 return GetAgentByUUID(profile.ID);
287 }
288
289 /// <summary>
290 /// Returns an agent session by account UUID
291 /// </summary>
292 /// <param name="uuid">The accounts UUID</param>
293 /// <returns>The users session</returns>
294 override public UserAgentData GetAgentByUUID(UUID uuid)
295 {
296 string sql = string.Format("SELECT * FROM {0} WHERE UUID = @uuid", m_agentsTableName);
297 using (AutoClosingSqlCommand command = database.Query(sql))
298 {
299 command.Parameters.Add(database.CreateParameter("uuid", uuid));
300 try
301 {
302 using (SqlDataReader reader = command.ExecuteReader())
303 {
304 return readAgentRow(reader);
305 }
306 }
307 catch (Exception e)
308 {
309 m_log.ErrorFormat("[USER DB] Error updating agentdata by UUID, error: {0}", e.Message);
310 return null;
311 }
312 }
313 }
314
315 /// <summary>
316 /// Creates a new agent
317 /// </summary>
318 /// <param name="agent">The agent to create</param>
319 override public void AddNewUserAgent(UserAgentData agent)
320 {
321 try
322 {
323 InsertUpdateAgentRow(agent);
324 }
325 catch (Exception e)
326 {
327 m_log.ErrorFormat("[USER DB] Error adding new agentdata, error: {0}", e.Message);
328 }
329 }
330
331 #endregion
332
333 #region User Friends List Data
334
335 /// <summary>
336 /// Add a new friend in the friendlist
337 /// </summary>
338 /// <param name="friendlistowner">UUID of the friendlist owner</param>
339 /// <param name="friend">Friend's UUID</param>
340 /// <param name="perms">Permission flag</param>
341 override public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
342 {
343 int dtvalue = Util.UnixTimeSinceEpoch();
344 string sql = string.Format(@"INSERT INTO {0}
345 (ownerID,friendID,friendPerms,datetimestamp)
346 VALUES
347 (@ownerID,@friendID,@friendPerms,@datetimestamp)", m_userFriendsTableName);
348 using (AutoClosingSqlCommand command = database.Query(sql))
349 {
350 command.Parameters.Add(database.CreateParameter("ownerID", friendlistowner));
351 command.Parameters.Add(database.CreateParameter("friendID", friend));
352 command.Parameters.Add(database.CreateParameter("friendPerms", perms));
353 command.Parameters.Add(database.CreateParameter("datetimestamp", dtvalue));
354 command.ExecuteNonQuery();
355
356 try
357 {
358 sql = string.Format(@"INSERT INTO {0}
359 (ownerID,friendID,friendPerms,datetimestamp)
360 VALUES
361 (@friendID,@ownerID,@friendPerms,@datetimestamp)", m_userFriendsTableName);
362 command.CommandText = sql;
363 command.ExecuteNonQuery();
364 }
365 catch (Exception e)
366 {
367 m_log.ErrorFormat("[USER DB] Error adding new userfriend, error: {0}", e.Message);
368 return;
369 }
370 }
371 }
372
373 /// <summary>
374 /// Remove an friend from the friendlist
375 /// </summary>
376 /// <param name="friendlistowner">UUID of the friendlist owner</param>
377 /// <param name="friend">UUID of the not-so-friendly user to remove from the list</param>
378 override public void RemoveUserFriend(UUID friendlistowner, UUID friend)
379 {
380 string sql = string.Format(@"DELETE from {0}
381 WHERE ownerID = @ownerID
382 AND friendID = @friendID", m_userFriendsTableName);
383 using (AutoClosingSqlCommand command = database.Query(sql))
384 {
385 command.Parameters.Add(database.CreateParameter("@ownerID", friendlistowner));
386 command.Parameters.Add(database.CreateParameter("@friendID", friend));
387 command.ExecuteNonQuery();
388 sql = string.Format(@"DELETE from {0}
389 WHERE ownerID = @friendID
390 AND friendID = @ownerID", m_userFriendsTableName);
391 command.CommandText = sql;
392 try
393 {
394 command.ExecuteNonQuery();
395 }
396 catch (Exception e)
397 {
398 m_log.ErrorFormat("[USER DB] Error removing userfriend, error: {0}", e.Message);
399 }
400 }
401 }
402
403 /// <summary>
404 /// Update friendlist permission flag for a friend
405 /// </summary>
406 /// <param name="friendlistowner">UUID of the friendlist owner</param>
407 /// <param name="friend">UUID of the friend</param>
408 /// <param name="perms">new permission flag</param>
409 override public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
410 {
411 string sql = string.Format(@"UPDATE {0} SET friendPerms = @friendPerms
412 WHERE ownerID = @ownerID
413 AND friendID = @friendID", m_userFriendsTableName);
414 using (AutoClosingSqlCommand command = database.Query(sql))
415 {
416 command.Parameters.Add(database.CreateParameter("@ownerID", friendlistowner));
417 command.Parameters.Add(database.CreateParameter("@friendID", friend));
418 command.Parameters.Add(database.CreateParameter("@friendPerms", perms));
419
420 try
421 {
422 command.ExecuteNonQuery();
423 }
424 catch (Exception e)
425 {
426 m_log.ErrorFormat("[USER DB] Error updating userfriend, error: {0}", e.Message);
427 }
428 }
429 }
430
431 /// <summary>
432 /// Get (fetch?) the user's friendlist
433 /// </summary>
434 /// <param name="friendlistowner">UUID of the friendlist owner</param>
435 /// <returns>Friendlist list</returns>
436 override public List<FriendListItem> GetUserFriendList(UUID friendlistowner)
437 {
438 List<FriendListItem> friendList = new List<FriendListItem>();
439
440 //Left Join userfriends to itself
441 string sql = string.Format(@"SELECT a.ownerID, a.friendID, a.friendPerms, b.friendPerms AS ownerperms
442 FROM {0} as a, {0} as b
443 WHERE a.ownerID = @ownerID
444 AND b.ownerID = a.friendID
445 AND b.friendID = a.ownerID", m_userFriendsTableName);
446 using (AutoClosingSqlCommand command = database.Query(sql))
447 {
448 command.Parameters.Add(database.CreateParameter("@ownerID", friendlistowner));
449 try
450 {
451 using (SqlDataReader reader = command.ExecuteReader())
452 {
453 while (reader.Read())
454 {
455 FriendListItem fli = new FriendListItem();
456 fli.FriendListOwner = new UUID((Guid)reader["ownerID"]);
457 fli.Friend = new UUID((Guid)reader["friendID"]);
458 fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]);
459
460 // This is not a real column in the database table, it's a joined column from the opposite record
461 fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]);
462 friendList.Add(fli);
463 }
464 }
465 }
466 catch (Exception e)
467 {
468 m_log.ErrorFormat("[USER DB] Error updating userfriend, error: {0}", e.Message);
469 }
470 }
471 return friendList;
472 }
473
474 override public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids)
475 {
476 Dictionary<UUID, FriendRegionInfo> infos = new Dictionary<UUID,FriendRegionInfo>();
477 try
478 {
479 foreach (UUID uuid in uuids)
480 {
481 string sql = string.Format(@"SELECT agentOnline,currentHandle
482 FROM {0} WHERE UUID = @uuid", m_agentsTableName);
483 using (AutoClosingSqlCommand command = database.Query(sql))
484 {
485 command.Parameters.Add(database.CreateParameter("@uuid", uuid));
486 using (SqlDataReader reader = command.ExecuteReader())
487 {
488 while (reader.Read())
489 {
490 FriendRegionInfo fri = new FriendRegionInfo();
491 fri.isOnline = (byte)reader["agentOnline"] != 0;
492 fri.regionHandle = Convert.ToUInt64(reader["currentHandle"].ToString());
493
494 infos[uuid] = fri;
495 }
496 }
497 }
498 }
499 }
500 catch (Exception e)
501 {
502 m_log.Warn("[MSSQL]: Got exception on trying to find friends regions:", e);
503 }
504
505 return infos;
506 }
507 #endregion
508
509 #region Money functions (not used)
510
511 /// <summary>
512 /// Performs a money transfer request between two accounts
513 /// </summary>
514 /// <param name="from">The senders account ID</param>
515 /// <param name="to">The receivers account ID</param>
516 /// <param name="amount">The amount to transfer</param>
517 /// <returns>false</returns>
518 override public bool MoneyTransferRequest(UUID from, UUID to, uint amount)
519 {
520 return false;
521 }
522
523 /// <summary>
524 /// Performs an inventory transfer request between two accounts
525 /// </summary>
526 /// <remarks>TODO: Move to inventory server</remarks>
527 /// <param name="from">The senders account ID</param>
528 /// <param name="to">The receivers account ID</param>
529 /// <param name="item">The item to transfer</param>
530 /// <returns>false</returns>
531 override public bool InventoryTransferRequest(UUID from, UUID to, UUID item)
532 {
533 return false;
534 }
535
536 #endregion
537
538 #region Appearance methods
539
540 /// <summary>
541 /// Gets the user appearance.
542 /// </summary>
543 /// <param name="user">The user.</param>
544 /// <returns></returns>
545 override public AvatarAppearance GetUserAppearance(UUID user)
546 {
547 try
548 {
549 AvatarAppearance appearance = new AvatarAppearance();
550 string sql = "SELECT * FROM avatarappearance WHERE owner = @UUID";
551 using (AutoClosingSqlCommand command = database.Query(sql))
552 {
553 command.Parameters.Add(database.CreateParameter("@UUID", user));
554 using (SqlDataReader reader = command.ExecuteReader())
555 {
556 if (reader.Read())
557 appearance = readUserAppearance(reader);
558 else
559 {
560 m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString());
561 return null;
562 }
563
564 }
565 }
566
567 appearance.SetAttachments(GetUserAttachments(user));
568
569 return appearance;
570 }
571 catch (Exception e)
572 {
573 m_log.ErrorFormat("[USER DB] Error updating userfriend, error: {0}", e.Message);
574 }
575 return null;
576 }
577
578 /// <summary>
579 /// Update a user appearence into database
580 /// </summary>
581 /// <param name="user">the used UUID</param>
582 /// <param name="appearance">the appearence</param>
583 override public void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
584 {
585 string sql = @"DELETE FROM avatarappearance WHERE owner=@owner;
586 INSERT INTO avatarappearance
587 (owner, serial, visual_params, texture, avatar_height,
588 body_item, body_asset, skin_item, skin_asset, hair_item,
589 hair_asset, eyes_item, eyes_asset, shirt_item, shirt_asset,
590 pants_item, pants_asset, shoes_item, shoes_asset, socks_item,
591 socks_asset, jacket_item, jacket_asset, gloves_item, gloves_asset,
592 undershirt_item, undershirt_asset, underpants_item, underpants_asset,
593 skirt_item, skirt_asset)
594 VALUES
595 (@owner, @serial, @visual_params, @texture, @avatar_height,
596 @body_item, @body_asset, @skin_item, @skin_asset, @hair_item,
597 @hair_asset, @eyes_item, @eyes_asset, @shirt_item, @shirt_asset,
598 @pants_item, @pants_asset, @shoes_item, @shoes_asset, @socks_item,
599 @socks_asset, @jacket_item, @jacket_asset, @gloves_item, @gloves_asset,
600 @undershirt_item, @undershirt_asset, @underpants_item, @underpants_asset,
601 @skirt_item, @skirt_asset)";
602
603 using (AutoClosingSqlCommand cmd = database.Query(sql))
604 {
605 cmd.Parameters.Add(database.CreateParameter("@owner", appearance.Owner));
606 cmd.Parameters.Add(database.CreateParameter("@serial", appearance.Serial));
607 cmd.Parameters.Add(database.CreateParameter("@visual_params", appearance.VisualParams));
608 cmd.Parameters.Add(database.CreateParameter("@texture", appearance.Texture.GetBytes()));
609 cmd.Parameters.Add(database.CreateParameter("@avatar_height", appearance.AvatarHeight));
610 cmd.Parameters.Add(database.CreateParameter("@body_item", appearance.BodyItem));
611 cmd.Parameters.Add(database.CreateParameter("@body_asset", appearance.BodyAsset));
612 cmd.Parameters.Add(database.CreateParameter("@skin_item", appearance.SkinItem));
613 cmd.Parameters.Add(database.CreateParameter("@skin_asset", appearance.SkinAsset));
614 cmd.Parameters.Add(database.CreateParameter("@hair_item", appearance.HairItem));
615 cmd.Parameters.Add(database.CreateParameter("@hair_asset", appearance.HairAsset));
616 cmd.Parameters.Add(database.CreateParameter("@eyes_item", appearance.EyesItem));
617 cmd.Parameters.Add(database.CreateParameter("@eyes_asset", appearance.EyesAsset));
618 cmd.Parameters.Add(database.CreateParameter("@shirt_item", appearance.ShirtItem));
619 cmd.Parameters.Add(database.CreateParameter("@shirt_asset", appearance.ShirtAsset));
620 cmd.Parameters.Add(database.CreateParameter("@pants_item", appearance.PantsItem));
621 cmd.Parameters.Add(database.CreateParameter("@pants_asset", appearance.PantsAsset));
622 cmd.Parameters.Add(database.CreateParameter("@shoes_item", appearance.ShoesItem));
623 cmd.Parameters.Add(database.CreateParameter("@shoes_asset", appearance.ShoesAsset));
624 cmd.Parameters.Add(database.CreateParameter("@socks_item", appearance.SocksItem));
625 cmd.Parameters.Add(database.CreateParameter("@socks_asset", appearance.SocksAsset));
626 cmd.Parameters.Add(database.CreateParameter("@jacket_item", appearance.JacketItem));
627 cmd.Parameters.Add(database.CreateParameter("@jacket_asset", appearance.JacketAsset));
628 cmd.Parameters.Add(database.CreateParameter("@gloves_item", appearance.GlovesItem));
629 cmd.Parameters.Add(database.CreateParameter("@gloves_asset", appearance.GlovesAsset));
630 cmd.Parameters.Add(database.CreateParameter("@undershirt_item", appearance.UnderShirtItem));
631 cmd.Parameters.Add(database.CreateParameter("@undershirt_asset", appearance.UnderShirtAsset));
632 cmd.Parameters.Add(database.CreateParameter("@underpants_item", appearance.UnderPantsItem));
633 cmd.Parameters.Add(database.CreateParameter("@underpants_asset", appearance.UnderPantsAsset));
634 cmd.Parameters.Add(database.CreateParameter("@skirt_item", appearance.SkirtItem));
635 cmd.Parameters.Add(database.CreateParameter("@skirt_asset", appearance.SkirtAsset));
636
637 try
638 {
639 cmd.ExecuteNonQuery();
640 }
641 catch (Exception e)
642 {
643 m_log.ErrorFormat("[USER DB] Error updating user appearance, error: {0}", e.Message);
644 }
645 }
646 UpdateUserAttachments(user, appearance.GetAttachments());
647 }
648
649 #endregion
650
651 #region Attachment methods
652
653 /// <summary>
654 /// Gets all attachment of a agent.
655 /// </summary>
656 /// <param name="agentID">agent ID.</param>
657 /// <returns></returns>
658 public Hashtable GetUserAttachments(UUID agentID)
659 {
660 Hashtable returnTable = new Hashtable();
661 string sql = "select attachpoint, item, asset from avatarattachments where UUID = @uuid";
662 using (AutoClosingSqlCommand command = database.Query(sql, database.CreateParameter("@uuid", agentID)))
663 {
664 using (SqlDataReader reader = command.ExecuteReader())
665 {
666 while (reader.Read())
667 {
668 int attachpoint = Convert.ToInt32(reader["attachpoint"]);
669 if (returnTable.ContainsKey(attachpoint))
670 continue;
671 Hashtable item = new Hashtable();
672 item.Add("item", reader["item"].ToString());
673 item.Add("asset", reader["asset"].ToString());
674
675 returnTable.Add(attachpoint, item);
676 }
677 }
678 }
679 return returnTable;
680 }
681
682 /// <summary>
683 /// Updates all attachments of the agent.
684 /// </summary>
685 /// <param name="agentID">agentID.</param>
686 /// <param name="data">data with all items on attachmentpoints</param>
687 public void UpdateUserAttachments(UUID agentID, Hashtable data)
688 {
689 string sql = "DELETE FROM avatarattachments WHERE UUID = @uuid";
690
691 using (AutoClosingSqlCommand command = database.Query(sql))
692 {
693 command.Parameters.Add(database.CreateParameter("uuid", agentID));
694 command.ExecuteNonQuery();
695 }
696 if (data == null)
697 return;
698
699 sql = @"INSERT INTO avatarattachments (UUID, attachpoint, item, asset)
700 VALUES (@uuid, @attachpoint, @item, @asset)";
701
702 using (AutoClosingSqlCommand command = database.Query(sql))
703 {
704 bool firstTime = true;
705 foreach (DictionaryEntry e in data)
706 {
707 int attachpoint = Convert.ToInt32(e.Key);
708
709 Hashtable item = (Hashtable)e.Value;
710
711 if (firstTime)
712 {
713 command.Parameters.Add(database.CreateParameter("@uuid", agentID));
714 command.Parameters.Add(database.CreateParameter("@attachpoint", attachpoint));
715 command.Parameters.Add(database.CreateParameter("@item", new UUID(item["item"].ToString())));
716 command.Parameters.Add(database.CreateParameter("@asset", new UUID(item["asset"].ToString())));
717 firstTime = false;
718 }
719 command.Parameters["@uuid"].Value = agentID.Guid; //.ToString();
720 command.Parameters["@attachpoint"].Value = attachpoint;
721 command.Parameters["@item"].Value = new Guid(item["item"].ToString());
722 command.Parameters["@asset"].Value = new Guid(item["asset"].ToString());
723
724 try
725 {
726 command.ExecuteNonQuery();
727 }
728 catch (Exception ex)
729 {
730 m_log.DebugFormat("[USER DB] : Error adding user attachment. {0}", ex.Message);
731 }
732 }
733 }
734 }
735
736 /// <summary>
737 /// Resets all attachments of a agent in the database.
738 /// </summary>
739 /// <param name="agentID">agentID.</param>
740 override public void ResetAttachments(UUID agentID)
741 {
742 string sql = "UPDATE avatarattachments SET asset = '00000000-0000-0000-0000-000000000000' WHERE UUID = @uuid";
743 using (AutoClosingSqlCommand command = database.Query(sql))
744 {
745 command.Parameters.Add(database.CreateParameter("uuid", agentID));
746 command.ExecuteNonQuery();
747 }
748 }
749
750 override public void LogoutUsers(UUID regionID)
751 {
752 }
753
754 #endregion
755
756 #region Other public methods
757
758 /// <summary>
759 ///
760 /// </summary>
761 /// <param name="queryID"></param>
762 /// <param name="query"></param>
763 /// <returns></returns>
764 override public List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query)
765 {
766 List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
767 string[] querysplit = query.Split(' ');
768 if (querysplit.Length == 2)
769 {
770 try
771 {
772 string sql = string.Format(@"SELECT UUID,username,lastname FROM {0}
773 WHERE username LIKE @first AND lastname LIKE @second", m_usersTableName);
774 using (AutoClosingSqlCommand command = database.Query(sql))
775 {
776 //Add wildcard to the search
777 command.Parameters.Add(database.CreateParameter("first", querysplit[0] + "%"));
778 command.Parameters.Add(database.CreateParameter("second", querysplit[1] + "%"));
779 using (SqlDataReader reader = command.ExecuteReader())
780 {
781 while (reader.Read())
782 {
783 AvatarPickerAvatar user = new AvatarPickerAvatar();
784 user.AvatarID = new UUID((Guid)reader["UUID"]);
785 user.firstName = (string)reader["username"];
786 user.lastName = (string)reader["lastname"];
787 returnlist.Add(user);
788 }
789 }
790 }
791 }
792 catch (Exception e)
793 {
794 m_log.Error(e.ToString());
795 }
796 }
797 else if (querysplit.Length == 1)
798 {
799 try
800 {
801 string sql = string.Format(@"SELECT UUID,username,lastname FROM {0}
802 WHERE username LIKE @first OR lastname LIKE @first", m_usersTableName);
803 using (AutoClosingSqlCommand command = database.Query(sql))
804 {
805 command.Parameters.Add(database.CreateParameter("first", querysplit[0] + "%"));
806
807 using (SqlDataReader reader = command.ExecuteReader())
808 {
809 while (reader.Read())
810 {
811 AvatarPickerAvatar user = new AvatarPickerAvatar();
812 user.AvatarID = new UUID((Guid)reader["UUID"]);
813 user.firstName = (string)reader["username"];
814 user.lastName = (string)reader["lastname"];
815 returnlist.Add(user);
816 }
817 }
818 }
819 }
820 catch (Exception e)
821 {
822 m_log.Error(e.ToString());
823 }
824 }
825 return returnlist;
826 }
827
828 /// <summary>
829 /// Store a weblogin key
830 /// </summary>
831 /// <param name="AgentID">The agent UUID</param>
832 /// <param name="WebLoginKey">the WebLogin Key</param>
833 /// <remarks>unused ?</remarks>
834 override public void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey)
835 {
836 UserProfileData user = GetUserByUUID(AgentID);
837 user.WebLoginKey = WebLoginKey;
838 UpdateUserProfile(user);
839 }
840
841 /// <summary>
842 /// Database provider name
843 /// </summary>
844 /// <returns>Provider name</returns>
845 override public string Name
846 {
847 get { return "MSSQL Userdata Interface"; }
848 }
849
850 /// <summary>
851 /// Database provider version
852 /// </summary>
853 /// <returns>provider version</returns>
854 override public string Version
855 {
856 get { return database.getVersion(); }
857 }
858
859 #endregion
860
861 #region Private functions
862
863 /// <summary>
864 /// Reads a one item from an SQL result
865 /// </summary>
866 /// <param name="reader">The SQL Result</param>
867 /// <returns>the item read</returns>
868 private static AvatarAppearance readUserAppearance(SqlDataReader reader)
869 {
870 try
871 {
872 AvatarAppearance appearance = new AvatarAppearance();
873
874 appearance.Owner = new UUID((Guid)reader["owner"]);
875 appearance.Serial = Convert.ToInt32(reader["serial"]);
876 appearance.VisualParams = (byte[])reader["visual_params"];
877 appearance.Texture = new Primitive.TextureEntry((byte[])reader["texture"], 0, ((byte[])reader["texture"]).Length);
878 appearance.AvatarHeight = (float)Convert.ToDouble(reader["avatar_height"]);
879 appearance.BodyItem = new UUID((Guid)reader["body_item"]);
880 appearance.BodyAsset = new UUID((Guid)reader["body_asset"]);
881 appearance.SkinItem = new UUID((Guid)reader["skin_item"]);
882 appearance.SkinAsset = new UUID((Guid)reader["skin_asset"]);
883 appearance.HairItem = new UUID((Guid)reader["hair_item"]);
884 appearance.HairAsset = new UUID((Guid)reader["hair_asset"]);
885 appearance.EyesItem = new UUID((Guid)reader["eyes_item"]);
886 appearance.EyesAsset = new UUID((Guid)reader["eyes_asset"]);
887 appearance.ShirtItem = new UUID((Guid)reader["shirt_item"]);
888 appearance.ShirtAsset = new UUID((Guid)reader["shirt_asset"]);
889 appearance.PantsItem = new UUID((Guid)reader["pants_item"]);
890 appearance.PantsAsset = new UUID((Guid)reader["pants_asset"]);
891 appearance.ShoesItem = new UUID((Guid)reader["shoes_item"]);
892 appearance.ShoesAsset = new UUID((Guid)reader["shoes_asset"]);
893 appearance.SocksItem = new UUID((Guid)reader["socks_item"]);
894 appearance.SocksAsset = new UUID((Guid)reader["socks_asset"]);
895 appearance.JacketItem = new UUID((Guid)reader["jacket_item"]);
896 appearance.JacketAsset = new UUID((Guid)reader["jacket_asset"]);
897 appearance.GlovesItem = new UUID((Guid)reader["gloves_item"]);
898 appearance.GlovesAsset = new UUID((Guid)reader["gloves_asset"]);
899 appearance.UnderShirtItem = new UUID((Guid)reader["undershirt_item"]);
900 appearance.UnderShirtAsset = new UUID((Guid)reader["undershirt_asset"]);
901 appearance.UnderPantsItem = new UUID((Guid)reader["underpants_item"]);
902 appearance.UnderPantsAsset = new UUID((Guid)reader["underpants_asset"]);
903 appearance.SkirtItem = new UUID((Guid)reader["skirt_item"]);
904 appearance.SkirtAsset = new UUID((Guid)reader["skirt_asset"]);
905
906 return appearance;
907 }
908 catch (SqlException e)
909 {
910 m_log.Error(e.ToString());
911 }
912
913 return null;
914 }
915
916 /// <summary>
917 /// Insert/Update a agent row in the DB.
918 /// </summary>
919 /// <param name="agentdata">agentdata.</param>
920 private void InsertUpdateAgentRow(UserAgentData agentdata)
921 {
922 string sql = @"
923
924IF EXISTS (SELECT * FROM agents WHERE UUID = @UUID)
925 BEGIN
926 UPDATE agents SET UUID = @UUID, sessionID = @sessionID, secureSessionID = @secureSessionID, agentIP = @agentIP, agentPort = @agentPort, agentOnline = @agentOnline, loginTime = @loginTime, logoutTime = @logoutTime, currentRegion = @currentRegion, currentHandle = @currentHandle, currentPos = @currentPos
927 WHERE UUID = @UUID
928 END
929ELSE
930 BEGIN
931 INSERT INTO
932 agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos) VALUES
933 (@UUID, @sessionID, @secureSessionID, @agentIP, @agentPort, @agentOnline, @loginTime, @logoutTime, @currentRegion, @currentHandle, @currentPos)
934 END
935";
936
937 using (AutoClosingSqlCommand command = database.Query(sql))
938 {
939 command.Parameters.Add(database.CreateParameter("@UUID", agentdata.ProfileID));
940 command.Parameters.Add(database.CreateParameter("@sessionID", agentdata.SessionID));
941 command.Parameters.Add(database.CreateParameter("@secureSessionID", agentdata.SecureSessionID));
942 command.Parameters.Add(database.CreateParameter("@agentIP", agentdata.AgentIP));
943 command.Parameters.Add(database.CreateParameter("@agentPort", agentdata.AgentPort));
944 command.Parameters.Add(database.CreateParameter("@agentOnline", agentdata.AgentOnline));
945 command.Parameters.Add(database.CreateParameter("@loginTime", agentdata.LoginTime));
946 command.Parameters.Add(database.CreateParameter("@logoutTime", agentdata.LogoutTime));
947 command.Parameters.Add(database.CreateParameter("@currentRegion", agentdata.Region));
948 command.Parameters.Add(database.CreateParameter("@currentHandle", agentdata.Handle));
949 command.Parameters.Add(database.CreateParameter("@currentPos", "<" + ((int)agentdata.Position.X) + "," + ((int)agentdata.Position.Y) + "," + ((int)agentdata.Position.Z) + ">"));
950
951 command.Transaction = command.Connection.BeginTransaction(IsolationLevel.Serializable);
952 try
953 {
954 if (command.ExecuteNonQuery() > 0)
955 {
956 command.Transaction.Commit();
957 return;
958 }
959
960 command.Transaction.Rollback();
961 return;
962 }
963 catch (Exception e)
964 {
965 command.Transaction.Rollback();
966 m_log.Error(e.ToString());
967 return;
968 }
969 }
970
971 }
972
973 /// <summary>
974 /// Reads an agent row from a database reader
975 /// </summary>
976 /// <param name="reader">An active database reader</param>
977 /// <returns>A user session agent</returns>
978 private UserAgentData readAgentRow(SqlDataReader reader)
979 {
980 UserAgentData retval = new UserAgentData();
981
982 if (reader.Read())
983 {
984 // Agent IDs
985 retval.ProfileID = new UUID((Guid)reader["UUID"]);
986 retval.SessionID = new UUID((Guid)reader["sessionID"]);
987 retval.SecureSessionID = new UUID((Guid)reader["secureSessionID"]);
988
989 // Agent Who?
990 retval.AgentIP = (string)reader["agentIP"];
991 retval.AgentPort = Convert.ToUInt32(reader["agentPort"].ToString());
992 retval.AgentOnline = Convert.ToInt32(reader["agentOnline"].ToString()) != 0;
993
994 // Login/Logout times (UNIX Epoch)
995 retval.LoginTime = Convert.ToInt32(reader["loginTime"].ToString());
996 retval.LogoutTime = Convert.ToInt32(reader["logoutTime"].ToString());
997
998 // Current position
999 retval.Region = new UUID((Guid)reader["currentRegion"]);
1000 retval.Handle = Convert.ToUInt64(reader["currentHandle"].ToString());
1001 Vector3 tmp_v;
1002 Vector3.TryParse((string)reader["currentPos"], out tmp_v);
1003 retval.Position = tmp_v;
1004
1005 }
1006 else
1007 {
1008 return null;
1009 }
1010 return retval;
1011 }
1012
1013 /// <summary>
1014 /// Creates a new user and inserts it into the database
1015 /// </summary>
1016 /// <param name="uuid">User ID</param>
1017 /// <param name="username">First part of the login</param>
1018 /// <param name="lastname">Second part of the login</param>
1019 /// <param name="email">Email of person</param>
1020 /// <param name="passwordHash">A salted hash of the users password</param>
1021 /// <param name="passwordSalt">The salt used for the password hash</param>
1022 /// <param name="homeRegion">A regionHandle of the users home region</param>
1023 /// <param name="homeLocX">Home region position vector</param>
1024 /// <param name="homeLocY">Home region position vector</param>
1025 /// <param name="homeLocZ">Home region position vector</param>
1026 /// <param name="homeLookAtX">Home region 'look at' vector</param>
1027 /// <param name="homeLookAtY">Home region 'look at' vector</param>
1028 /// <param name="homeLookAtZ">Home region 'look at' vector</param>
1029 /// <param name="created">Account created (unix timestamp)</param>
1030 /// <param name="lastlogin">Last login (unix timestamp)</param>
1031 /// <param name="inventoryURI">Users inventory URI</param>
1032 /// <param name="assetURI">Users asset URI</param>
1033 /// <param name="canDoMask">I can do mask</param>
1034 /// <param name="wantDoMask">I want to do mask</param>
1035 /// <param name="aboutText">Profile text</param>
1036 /// <param name="firstText">Firstlife text</param>
1037 /// <param name="profileImage">UUID for profile image</param>
1038 /// <param name="firstImage">UUID for firstlife image</param>
1039 /// <param name="webLoginKey">web login key</param>
1040 /// <param name="homeRegionID">homeregion UUID</param>
1041 /// <param name="godLevel">has the user godlevel</param>
1042 /// <param name="userFlags">unknown</param>
1043 /// <param name="customType">unknown</param>
1044 /// <param name="partnerID">UUID of partner</param>
1045 /// <returns>Success?</returns>
1046 private void InsertUserRow(UUID uuid, string username, string lastname, string email, string passwordHash,
1047 string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ,
1048 float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
1049 string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
1050 string aboutText, string firstText,
1051 UUID profileImage, UUID firstImage, UUID webLoginKey, UUID homeRegionID,
1052 int godLevel, int userFlags, string customType, UUID partnerID)
1053 {
1054 string sql = string.Format(@"INSERT INTO {0}
1055 ([UUID], [username], [lastname], [email], [passwordHash], [passwordSalt],
1056 [homeRegion], [homeLocationX], [homeLocationY], [homeLocationZ], [homeLookAtX],
1057 [homeLookAtY], [homeLookAtZ], [created], [lastLogin], [userInventoryURI],
1058 [userAssetURI], [profileCanDoMask], [profileWantDoMask], [profileAboutText],
1059 [profileFirstText], [profileImage], [profileFirstImage], [webLoginKey],
1060 [homeRegionID], [userFlags], [godLevel], [customType], [partner])
1061 VALUES
1062 (@UUID, @username, @lastname, @email, @passwordHash, @passwordSalt,
1063 @homeRegion, @homeLocationX, @homeLocationY, @homeLocationZ, @homeLookAtX,
1064 @homeLookAtY, @homeLookAtZ, @created, @lastLogin, @userInventoryURI,
1065 @userAssetURI, @profileCanDoMask, @profileWantDoMask, @profileAboutText,
1066 @profileFirstText, @profileImage, @profileFirstImage, @webLoginKey,
1067 @homeRegionID, @userFlags, @godLevel, @customType, @partner)", m_usersTableName);
1068
1069 try
1070 {
1071 using (AutoClosingSqlCommand command = database.Query(sql))
1072 {
1073 command.Parameters.Add(database.CreateParameter("UUID", uuid));
1074 command.Parameters.Add(database.CreateParameter("username", username));
1075 command.Parameters.Add(database.CreateParameter("lastname", lastname));
1076 command.Parameters.Add(database.CreateParameter("email", email));
1077 command.Parameters.Add(database.CreateParameter("passwordHash", passwordHash));
1078 command.Parameters.Add(database.CreateParameter("passwordSalt", passwordSalt));
1079 command.Parameters.Add(database.CreateParameter("homeRegion", homeRegion));
1080 command.Parameters.Add(database.CreateParameter("homeLocationX", homeLocX));
1081 command.Parameters.Add(database.CreateParameter("homeLocationY", homeLocY));
1082 command.Parameters.Add(database.CreateParameter("homeLocationZ", homeLocZ));
1083 command.Parameters.Add(database.CreateParameter("homeLookAtX", homeLookAtX));
1084 command.Parameters.Add(database.CreateParameter("homeLookAtY", homeLookAtY));
1085 command.Parameters.Add(database.CreateParameter("homeLookAtZ", homeLookAtZ));
1086 command.Parameters.Add(database.CreateParameter("created", created));
1087 command.Parameters.Add(database.CreateParameter("lastLogin", lastlogin));
1088 command.Parameters.Add(database.CreateParameter("userInventoryURI", inventoryURI));
1089 command.Parameters.Add(database.CreateParameter("userAssetURI", assetURI));
1090 command.Parameters.Add(database.CreateParameter("profileCanDoMask", canDoMask));
1091 command.Parameters.Add(database.CreateParameter("profileWantDoMask", wantDoMask));
1092 command.Parameters.Add(database.CreateParameter("profileAboutText", aboutText));
1093 command.Parameters.Add(database.CreateParameter("profileFirstText", firstText));
1094 command.Parameters.Add(database.CreateParameter("profileImage", profileImage));
1095 command.Parameters.Add(database.CreateParameter("profileFirstImage", firstImage));
1096 command.Parameters.Add(database.CreateParameter("webLoginKey", webLoginKey));
1097 command.Parameters.Add(database.CreateParameter("homeRegionID", homeRegionID));
1098 command.Parameters.Add(database.CreateParameter("userFlags", userFlags));
1099 command.Parameters.Add(database.CreateParameter("godLevel", godLevel));
1100 command.Parameters.Add(database.CreateParameter("customType", customType));
1101 command.Parameters.Add(database.CreateParameter("partner", partnerID));
1102
1103 command.ExecuteNonQuery();
1104 return;
1105 }
1106 }
1107 catch (Exception e)
1108 {
1109 m_log.Error(e.ToString());
1110 return;
1111 }
1112 }
1113
1114 /// <summary>
1115 /// Reads a user profile from an active data reader
1116 /// </summary>
1117 /// <param name="reader">An active database reader</param>
1118 /// <returns>A user profile</returns>
1119 private static UserProfileData ReadUserRow(SqlDataReader reader)
1120 {
1121 UserProfileData retval = new UserProfileData();
1122
1123 if (reader.Read())
1124 {
1125 retval.ID = new UUID((Guid)reader["UUID"]);
1126 retval.FirstName = (string)reader["username"];
1127 retval.SurName = (string)reader["lastname"];
1128 if (reader.IsDBNull(reader.GetOrdinal("email")))
1129 retval.Email = "";
1130 else
1131 retval.Email = (string)reader["email"];
1132
1133 retval.PasswordHash = (string)reader["passwordHash"];
1134 retval.PasswordSalt = (string)reader["passwordSalt"];
1135
1136 retval.HomeRegion = Convert.ToUInt64(reader["homeRegion"].ToString());
1137 retval.HomeLocation = new Vector3(
1138 Convert.ToSingle(reader["homeLocationX"].ToString()),
1139 Convert.ToSingle(reader["homeLocationY"].ToString()),
1140 Convert.ToSingle(reader["homeLocationZ"].ToString()));
1141 retval.HomeLookAt = new Vector3(
1142 Convert.ToSingle(reader["homeLookAtX"].ToString()),
1143 Convert.ToSingle(reader["homeLookAtY"].ToString()),
1144 Convert.ToSingle(reader["homeLookAtZ"].ToString()));
1145
1146 if (reader.IsDBNull(reader.GetOrdinal("homeRegionID")))
1147 retval.HomeRegionID = UUID.Zero;
1148 else
1149 retval.HomeRegionID = new UUID((Guid)reader["homeRegionID"]);
1150
1151 retval.Created = Convert.ToInt32(reader["created"].ToString());
1152 retval.LastLogin = Convert.ToInt32(reader["lastLogin"].ToString());
1153
1154 if (reader.IsDBNull(reader.GetOrdinal("userInventoryURI")))
1155 retval.UserInventoryURI = "";
1156 else
1157 retval.UserInventoryURI = (string)reader["userInventoryURI"];
1158
1159 if (reader.IsDBNull(reader.GetOrdinal("userAssetURI")))
1160 retval.UserAssetURI = "";
1161 else
1162 retval.UserAssetURI = (string)reader["userAssetURI"];
1163
1164 retval.CanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString());
1165 retval.WantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString());
1166
1167
1168 if (reader.IsDBNull(reader.GetOrdinal("profileAboutText")))
1169 retval.AboutText = "";
1170 else
1171 retval.AboutText = (string)reader["profileAboutText"];
1172
1173 if (reader.IsDBNull(reader.GetOrdinal("profileFirstText")))
1174 retval.FirstLifeAboutText = "";
1175 else
1176 retval.FirstLifeAboutText = (string)reader["profileFirstText"];
1177
1178 if (reader.IsDBNull(reader.GetOrdinal("profileImage")))
1179 retval.Image = UUID.Zero;
1180 else
1181 retval.Image = new UUID((Guid)reader["profileImage"]);
1182
1183 if (reader.IsDBNull(reader.GetOrdinal("profileFirstImage")))
1184 retval.Image = UUID.Zero;
1185 else
1186 retval.FirstLifeImage = new UUID((Guid)reader["profileFirstImage"]);
1187
1188 if (reader.IsDBNull(reader.GetOrdinal("webLoginKey")))
1189 retval.WebLoginKey = UUID.Zero;
1190 else
1191 retval.WebLoginKey = new UUID((Guid)reader["webLoginKey"]);
1192
1193 retval.UserFlags = Convert.ToInt32(reader["userFlags"].ToString());
1194 retval.GodLevel = Convert.ToInt32(reader["godLevel"].ToString());
1195 if (reader.IsDBNull(reader.GetOrdinal("customType")))
1196 retval.CustomType = "";
1197 else
1198 retval.CustomType = reader["customType"].ToString();
1199
1200 if (reader.IsDBNull(reader.GetOrdinal("partner")))
1201 retval.Partner = UUID.Zero;
1202 else
1203 retval.Partner = new UUID((Guid)reader["partner"]);
1204 }
1205 else
1206 {
1207 return null;
1208 }
1209 return retval;
1210 }
1211 #endregion
1212 }
1213
1214}
diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
new file mode 100644
index 0000000..739eb55
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
@@ -0,0 +1,166 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using System.Data.SqlClient;
35using System.Reflection;
36using System.Text;
37using log4net;
38
39namespace OpenSim.Data.MSSQL
40{
41 public class MSSQLXInventoryData : IXInventoryData
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(
44 MethodBase.GetCurrentMethod().DeclaringType);
45
46 private MSSQLGenericTableHandler<XInventoryFolder> m_Folders;
47 private MSSQLItemHandler m_Items;
48
49 public MSSQLXInventoryData(string conn, string realm)
50 {
51 m_Folders = new MSSQLGenericTableHandler<XInventoryFolder>(
52 conn, "inventoryfolders", "InventoryStore");
53 m_Items = new MSSQLItemHandler(
54 conn, "inventoryitems", String.Empty);
55 }
56
57 public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
58 {
59 return m_Folders.Get(fields, vals);
60 }
61
62 public XInventoryItem[] GetItems(string[] fields, string[] vals)
63 {
64 return m_Items.Get(fields, vals);
65 }
66
67 public bool StoreFolder(XInventoryFolder folder)
68 {
69 return m_Folders.Store(folder);
70 }
71
72 public bool StoreItem(XInventoryItem item)
73 {
74 return m_Items.Store(item);
75 }
76
77 public bool DeleteFolders(string field, string val)
78 {
79 return m_Folders.Delete(field, val);
80 }
81
82 public bool DeleteItems(string field, string val)
83 {
84 return m_Items.Delete(field, val);
85 }
86
87 public bool MoveItem(string id, string newParent)
88 {
89 return m_Items.MoveItem(id, newParent);
90 }
91
92 public XInventoryItem[] GetActiveGestures(UUID principalID)
93 {
94 return m_Items.GetActiveGestures(principalID);
95 }
96
97 public int GetAssetPermissions(UUID principalID, UUID assetID)
98 {
99 return m_Items.GetAssetPermissions(principalID, assetID);
100 }
101 }
102
103 public class MSSQLItemHandler : MSSQLGenericTableHandler<XInventoryItem>
104 {
105 public MSSQLItemHandler(string c, string t, string m) :
106 base(c, t, m)
107 {
108 }
109
110 public bool MoveItem(string id, string newParent)
111 {
112 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
113 using (SqlCommand cmd = new SqlCommand())
114 {
115
116 cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm);
117 cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent));
118 cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
119 cmd.Connection = conn;
120 conn.Open();
121 return cmd.ExecuteNonQuery() == 0 ? false : true;
122 }
123 }
124
125 public XInventoryItem[] GetActiveGestures(UUID principalID)
126 {
127 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
128 using (SqlCommand cmd = new SqlCommand())
129 {
130 cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
131
132 cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString()));
133 cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture));
134 cmd.Connection = conn;
135 conn.Open();
136 return DoQuery(cmd);
137 }
138 }
139
140 public int GetAssetPermissions(UUID principalID, UUID assetID)
141 {
142 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
143 using (SqlCommand cmd = new SqlCommand())
144 {
145 cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
146 cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
147 cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString()));
148 cmd.Connection = conn;
149 conn.Open();
150 using (SqlDataReader reader = cmd.ExecuteReader())
151 {
152
153 int perms = 0;
154
155 if (reader.Read())
156 {
157 perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
158 }
159
160 return perms;
161 }
162
163 }
164 }
165 }
166}
diff --git a/OpenSim/Data/MSSQL/Resources/001_AuthStore.sql b/OpenSim/Data/MSSQL/Resources/001_AuthStore.sql
new file mode 100644
index 0000000..c70a193
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/001_AuthStore.sql
@@ -0,0 +1,17 @@
1BEGIN TRANSACTION
2
3CREATE TABLE [auth] (
4 [uuid] [uniqueidentifier] NOT NULL default '00000000-0000-0000-0000-000000000000',
5 [passwordHash] [varchar](32) NOT NULL,
6 [passwordSalt] [varchar](32) NOT NULL,
7 [webLoginKey] [varchar](255) NOT NULL,
8 [accountType] VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
9) ON [PRIMARY]
10
11CREATE TABLE [tokens] (
12 [uuid] [uniqueidentifier] NOT NULL default '00000000-0000-0000-0000-000000000000',
13 [token] [varchar](255) NOT NULL,
14 [validity] [datetime] NOT NULL )
15 ON [PRIMARY]
16
17COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/001_Avatar.sql b/OpenSim/Data/MSSQL/Resources/001_Avatar.sql
new file mode 100644
index 0000000..48f4c00
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/001_Avatar.sql
@@ -0,0 +1,15 @@
1BEGIN TRANSACTION
2
3CREATE TABLE [Avatars] (
4[PrincipalID] uniqueidentifier NOT NULL,
5[Name] varchar(32) NOT NULL,
6[Value] varchar(255) NOT NULL DEFAULT '',
7PRIMARY KEY CLUSTERED
8(
9 [PrincipalID] ASC, [Name] ASC
10)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
11) ON [PRIMARY]
12
13
14
15COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/001_FriendsStore.sql b/OpenSim/Data/MSSQL/Resources/001_FriendsStore.sql
new file mode 100644
index 0000000..94d240b
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/001_FriendsStore.sql
@@ -0,0 +1,11 @@
1BEGIN TRANSACTION
2
3CREATE TABLE [Friends] (
4[PrincipalID] uniqueidentifier NOT NULL,
5[Friend] varchar(255) NOT NULL,
6[Flags] char(16) NOT NULL DEFAULT '0',
7[Offered] varchar(32) NOT NULL DEFAULT 0)
8 ON [PRIMARY]
9
10
11COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/001_Presence.sql b/OpenSim/Data/MSSQL/Resources/001_Presence.sql
new file mode 100644
index 0000000..877881c
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/001_Presence.sql
@@ -0,0 +1,19 @@
1BEGIN TRANSACTION
2
3CREATE TABLE [Presence] (
4[UserID] varchar(255) NOT NULL,
5[RegionID] uniqueidentifier NOT NULL,
6[SessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
7[SecureSessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8[Online] char(5) NOT NULL DEFAULT 'false',
9[Login] char(16) NOT NULL DEFAULT '0',
10[Logout] char(16) NOT NULL DEFAULT '0',
11[Position] char(64) NOT NULL DEFAULT '<0,0,0>',
12[LookAt] char(64) NOT NULL DEFAULT '<0,0,0>',
13[HomeRegionID] uniqueidentifier NOT NULL,
14[HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
15[HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
16)
17 ON [PRIMARY]
18
19COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/001_UserAccount.sql b/OpenSim/Data/MSSQL/Resources/001_UserAccount.sql
new file mode 100644
index 0000000..3dbf8a4
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/001_UserAccount.sql
@@ -0,0 +1,14 @@
1CREATE TABLE [UserAccounts] (
2 [PrincipalID] uniqueidentifier NOT NULL,
3 [ScopeID] uniqueidentifier NOT NULL,
4 [FirstName] [varchar](64) NOT NULL,
5 [LastName] [varchar](64) NOT NULL,
6 [Email] [varchar](64) NULL,
7 [ServiceURLs] [text] NULL,
8 [Created] [int] default NULL,
9
10 PRIMARY KEY CLUSTERED
11(
12 [PrincipalID] ASC
13)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
14) ON [PRIMARY]
diff --git a/OpenSim/Data/MSSQL/Resources/002_AuthStore.sql b/OpenSim/Data/MSSQL/Resources/002_AuthStore.sql
new file mode 100644
index 0000000..daed955
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/002_AuthStore.sql
@@ -0,0 +1,6 @@
1BEGIN TRANSACTION
2
3INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users;
4
5
6COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/002_FriendsStore.sql b/OpenSim/Data/MSSQL/Resources/002_FriendsStore.sql
new file mode 100644
index 0000000..e67d20e
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/002_FriendsStore.sql
@@ -0,0 +1,6 @@
1BEGIN TRANSACTION
2
3INSERT INTO Friends (PrincipalID, Friend, Flags, Offered) SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
4
5
6COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/002_Presence.sql b/OpenSim/Data/MSSQL/Resources/002_Presence.sql
new file mode 100644
index 0000000..a67671d
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/002_Presence.sql
@@ -0,0 +1,6 @@
1BEGIN TRANSACTION
2
3CREATE UNIQUE INDEX SessionID ON Presence(SessionID);
4CREATE INDEX UserID ON Presence(UserID);
5
6COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/002_UserAccount.sql b/OpenSim/Data/MSSQL/Resources/002_UserAccount.sql
new file mode 100644
index 0000000..89d1f34
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/002_UserAccount.sql
@@ -0,0 +1,12 @@
1BEGIN TRANSACTION
2
3INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT [UUID] AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID,
4username AS FirstName,
5lastname AS LastName,
6email as Email, (
7'AssetServerURI=' +
8userAssetURI + ' InventoryServerURI=' + userInventoryURI + ' GatewayURI= HomeURI=') AS ServiceURLs,
9created as Created FROM users;
10
11
12COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/003_UserAccount.sql b/OpenSim/Data/MSSQL/Resources/003_UserAccount.sql
new file mode 100644
index 0000000..da0395b
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/003_UserAccount.sql
@@ -0,0 +1,9 @@
1BEGIN TRANSACTION
2
3CREATE UNIQUE INDEX PrincipalID ON UserAccounts(PrincipalID);
4CREATE INDEX Email ON UserAccounts(Email);
5CREATE INDEX FirstName ON UserAccounts(FirstName);
6CREATE INDEX LastName ON UserAccounts(LastName);
7CREATE INDEX Name ON UserAccounts(FirstName,LastName);
8
9COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/004_UserAccount.sql b/OpenSim/Data/MSSQL/Resources/004_UserAccount.sql
new file mode 100644
index 0000000..a9a9021
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/004_UserAccount.sql
@@ -0,0 +1,7 @@
1BEGIN TRANSACTION
2
3ALTER TABLE UserAccounts ADD UserLevel integer NOT NULL DEFAULT 0;
4ALTER TABLE UserAccounts ADD UserFlags integer NOT NULL DEFAULT 0;
5ALTER TABLE UserAccounts ADD UserTitle varchar(64) NOT NULL DEFAULT '';
6
7COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/007_GridStore.sql b/OpenSim/Data/MSSQL/Resources/007_GridStore.sql
new file mode 100644
index 0000000..0b66d40
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/007_GridStore.sql
@@ -0,0 +1,9 @@
1BEGIN TRANSACTION
2
3ALTER TABLE regions ADD [flags] integer NOT NULL DEFAULT 0;
4CREATE INDEX [flags] ON regions(flags);
5ALTER TABLE [regions] ADD [last_seen] integer NOT NULL DEFAULT 0;
6ALTER TABLE [regions] ADD [PrincipalID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
7ALTER TABLE [regions] ADD [Token] varchar(255) NOT NULL DEFAULT 0;
8
9COMMIT
diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs
index e51dc22..0fb9e78 100644
--- a/OpenSim/Data/Migration.cs
+++ b/OpenSim/Data/Migration.cs
@@ -128,7 +128,7 @@ namespace OpenSim.Data
128 return; 128 return;
129 129
130 // to prevent people from killing long migrations. 130 // to prevent people from killing long migrations.
131 m_log.InfoFormat("[MIGRATIONS] Upgrading {0} to latest revision.", _type); 131 m_log.InfoFormat("[MIGRATIONS] Upgrading {0} to latest revision {1}.", _type, migrations.Keys[migrations.Count - 1]);
132 m_log.Info("[MIGRATIONS] NOTE: this may take a while, don't interupt this process!"); 132 m_log.Info("[MIGRATIONS] NOTE: this may take a while, don't interupt this process!");
133 133
134 DbCommand cmd = _conn.CreateCommand(); 134 DbCommand cmd = _conn.CreateCommand();
@@ -138,7 +138,17 @@ namespace OpenSim.Data
138 cmd.CommandText = kvp.Value; 138 cmd.CommandText = kvp.Value;
139 // we need to up the command timeout to infinite as we might be doing long migrations. 139 // we need to up the command timeout to infinite as we might be doing long migrations.
140 cmd.CommandTimeout = 0; 140 cmd.CommandTimeout = 0;
141 cmd.ExecuteNonQuery(); 141 try
142 {
143 cmd.ExecuteNonQuery();
144 }
145 catch (Exception e)
146 {
147 m_log.DebugFormat("[MIGRATIONS] Cmd was {0}", cmd.CommandText);
148 m_log.DebugFormat("[MIGRATIONS]: An error has occurred in the migration {0}.\n This may mean you could see errors trying to run OpenSim. If you see database related errors, you will need to fix the issue manually. Continuing.", e.Message);
149 cmd.CommandText = "ROLLBACK;";
150 cmd.ExecuteNonQuery();
151 }
142 152
143 if (version == 0) 153 if (version == 0)
144 { 154 {
@@ -149,8 +159,9 @@ namespace OpenSim.Data
149 UpdateVersion(_type, newversion); 159 UpdateVersion(_type, newversion);
150 } 160 }
151 version = newversion; 161 version = newversion;
152 cmd.Dispose();
153 } 162 }
163
164 cmd.Dispose();
154 } 165 }
155 166
156 // private int MaxVersion() 167 // private int MaxVersion()
@@ -246,7 +257,8 @@ namespace OpenSim.Data
246 if (m.Success) 257 if (m.Success)
247 { 258 {
248 int version = int.Parse(m.Groups[1].ToString()); 259 int version = int.Parse(m.Groups[1].ToString());
249 if (version > after) { 260 if (version > after)
261 {
250 using (Stream resource = _assem.GetManifestResourceStream(s)) 262 using (Stream resource = _assem.GetManifestResourceStream(s))
251 { 263 {
252 using (StreamReader resourceReader = new StreamReader(resource)) 264 using (StreamReader resourceReader = new StreamReader(resource))
diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs
index 666c22f..d55369a 100644
--- a/OpenSim/Data/MySQL/MySQLAssetData.cs
+++ b/OpenSim/Data/MySQL/MySQLAssetData.cs
@@ -122,7 +122,7 @@ namespace OpenSim.Data.MySQL
122 { 122 {
123 if (dbReader.Read()) 123 if (dbReader.Read())
124 { 124 {
125 asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"]); 125 asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], UUID.Zero.ToString());
126 asset.Data = (byte[])dbReader["data"]; 126 asset.Data = (byte[])dbReader["data"];
127 asset.Description = (string)dbReader["description"]; 127 asset.Description = (string)dbReader["description"];
128 128
diff --git a/OpenSim/Services/UserService/UserService.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs
index e8b9fc3..5611302 100644
--- a/OpenSim/Services/UserService/UserService.cs
+++ b/OpenSim/Data/MySQL/MySQLAvatarData.cs
@@ -26,51 +26,42 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
30using Nini.Config;
31using OpenSim.Data;
32using OpenSim.Services.Interfaces;
33using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework;
36using MySql.Data.MySqlClient;
35 37
36namespace OpenSim.Services.UserAccountService 38namespace OpenSim.Data.MySQL
37{ 39{
38 public class UserAccountService : UserAccountServiceBase, IUserAccountService 40 /// <summary>
41 /// A MySQL Interface for the Grid Server
42 /// </summary>
43 public class MySQLAvatarData : MySQLGenericTableHandler<AvatarBaseData>,
44 IAvatarData
39 { 45 {
40 public UserAccountService(IConfigSource config) : base(config) 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 {
42 }
43 47
44 public UserAccount GetUserAccount(UUID scopeID, string firstName, 48 public MySQLAvatarData(string connectionString, string realm) :
45 string lastName) 49 base(connectionString, realm, "Avatar")
46 { 50 {
47 return null;
48 } 51 }
49 52
50 public UserAccount GetUserAccount(UUID scopeID, UUID userID) 53 public bool Delete(UUID principalID, string name)
51 { 54 {
52 return null; 55 MySqlCommand cmd = new MySqlCommand();
53 }
54 56
55 public bool SetHomePosition(UserAccount data, UUID regionID, UUID regionSecret) 57 cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
56 { 58 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
57 return false; 59 cmd.Parameters.AddWithValue("?Name", name);
58 }
59 60
60 public bool SetUserAccount(UserAccount data, UUID principalID, string token) 61 if (ExecuteNonQuery(cmd) > 0)
61 { 62 return true;
62 return false;
63 }
64 63
65 public bool CreateUserAccount(UserAccount data, UUID principalID, string token)
66 {
67 return false; 64 return false;
68 } 65 }
69
70 public List<UserAccount> GetUserAccount(UUID scopeID,
71 string query)
72 {
73 return null;
74 }
75 } 66 }
76} 67}
diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs
index 2eae2d8..d0c02f0 100644
--- a/OpenSim/Data/MySQL/MySQLEstateData.cs
+++ b/OpenSim/Data/MySQL/MySQLEstateData.cs
@@ -121,111 +121,110 @@ namespace OpenSim.Data.MySQL
121 } 121 }
122 } 122 }
123 123
124 public EstateSettings LoadEstateSettings(UUID regionID) 124 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
125 { 125 {
126 EstateSettings es = new EstateSettings();
127 es.OnSave += StoreEstateSettings;
128
129 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + 126 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) +
130 " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID"; 127 " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID";
131 128
132 bool migration = true; 129 using (MySqlCommand cmd = new MySqlCommand())
130 {
131 cmd.CommandText = sql;
132 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
133
134 return DoLoad(cmd, regionID, create);
135 }
136 }
137
138 private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
139 {
140 EstateSettings es = new EstateSettings();
141 es.OnSave += StoreEstateSettings;
133 142
134 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 143 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
135 { 144 {
136 dbcon.Open(); 145 dbcon.Open();
137 146
138 using (MySqlCommand cmd = dbcon.CreateCommand()) 147 cmd.Connection = dbcon;
139 {
140 cmd.CommandText = sql;
141 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
142 148
143 using (IDataReader r = cmd.ExecuteReader()) 149 bool found = false;
150
151 using (IDataReader r = cmd.ExecuteReader())
152 {
153 if (r.Read())
144 { 154 {
145 if (r.Read()) 155 found = true;
146 {
147 migration = false;
148 156
149 foreach (string name in FieldList) 157 foreach (string name in FieldList)
158 {
159 if (m_FieldMap[name].GetValue(es) is bool)
150 { 160 {
151 if (m_FieldMap[name].GetValue(es) is bool) 161 int v = Convert.ToInt32(r[name]);
152 { 162 if (v != 0)
153 int v = Convert.ToInt32(r[name]); 163 m_FieldMap[name].SetValue(es, true);
154 if (v != 0)
155 m_FieldMap[name].SetValue(es, true);
156 else
157 m_FieldMap[name].SetValue(es, false);
158 }
159 else if (m_FieldMap[name].GetValue(es) is UUID)
160 {
161 UUID uuid = UUID.Zero;
162
163 UUID.TryParse(r[name].ToString(), out uuid);
164 m_FieldMap[name].SetValue(es, uuid);
165 }
166 else 164 else
167 { 165 m_FieldMap[name].SetValue(es, false);
168 m_FieldMap[name].SetValue(es, r[name]); 166 }
169 } 167 else if (m_FieldMap[name].GetValue(es) is UUID)
168 {
169 UUID uuid = UUID.Zero;
170
171 UUID.TryParse(r[name].ToString(), out uuid);
172 m_FieldMap[name].SetValue(es, uuid);
173 }
174 else
175 {
176 m_FieldMap[name].SetValue(es, r[name]);
170 } 177 }
171 } 178 }
172 } 179 }
173 } 180 }
174 181
175 if (migration) 182 if (!found && create)
176 { 183 {
177 // Migration case 184 // Migration case
178 List<string> names = new List<string>(FieldList); 185 List<string> names = new List<string>(FieldList);
179 186
180 names.Remove("EstateID"); 187 names.Remove("EstateID");
181 188
182 sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; 189 string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
183 190
184 using (MySqlCommand cmd = dbcon.CreateCommand()) 191 using (MySqlCommand cmd2 = dbcon.CreateCommand())
185 { 192 {
186 cmd.CommandText = sql; 193 cmd2.CommandText = sql;
187 cmd.Parameters.Clear(); 194 cmd2.Parameters.Clear();
188 195
189 foreach (string name in FieldList) 196 foreach (string name in FieldList)
190 { 197 {
191 if (m_FieldMap[name].GetValue(es) is bool) 198 if (m_FieldMap[name].GetValue(es) is bool)
192 { 199 {
193 if ((bool)m_FieldMap[name].GetValue(es)) 200 if ((bool)m_FieldMap[name].GetValue(es))
194 cmd.Parameters.AddWithValue("?" + name, "1"); 201 cmd2.Parameters.AddWithValue("?" + name, "1");
195 else 202 else
196 cmd.Parameters.AddWithValue("?" + name, "0"); 203 cmd2.Parameters.AddWithValue("?" + name, "0");
197 } 204 }
198 else 205 else
199 { 206 {
200 cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); 207 cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
201 } 208 }
202 } 209 }
203 210
204 cmd.ExecuteNonQuery(); 211 cmd2.ExecuteNonQuery();
205 212
206 cmd.CommandText = "select LAST_INSERT_ID() as id"; 213 cmd2.CommandText = "select LAST_INSERT_ID() as id";
207 cmd.Parameters.Clear(); 214 cmd2.Parameters.Clear();
208 215
209 using (IDataReader r = cmd.ExecuteReader()) 216 using (IDataReader r = cmd2.ExecuteReader())
210 { 217 {
211 r.Read(); 218 r.Read();
212 es.EstateID = Convert.ToUInt32(r["id"]); 219 es.EstateID = Convert.ToUInt32(r["id"]);
213 } 220 }
214 221
215 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; 222 cmd2.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
216 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); 223 cmd2.Parameters.AddWithValue("?RegionID", regionID.ToString());
217 cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); 224 cmd2.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
218 225
219 // This will throw on dupe key 226 // This will throw on dupe key
220 try { cmd.ExecuteNonQuery(); } 227 try { cmd2.ExecuteNonQuery(); }
221 catch (Exception) { }
222
223 // Munge and transfer the ban list
224 cmd.Parameters.Clear();
225 cmd.CommandText = "insert into estateban select " + es.EstateID.ToString() + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID";
226 cmd.Parameters.AddWithValue("?UUID", regionID.ToString());
227
228 try { cmd.ExecuteNonQuery(); }
229 catch (Exception) { } 228 catch (Exception) { }
230 229
231 es.Save(); 230 es.Save();
@@ -398,5 +397,89 @@ namespace OpenSim.Data.MySQL
398 397
399 return uuids.ToArray(); 398 return uuids.ToArray();
400 } 399 }
400
401 public EstateSettings LoadEstateSettings(int estateID)
402 {
403 using (MySqlCommand cmd = new MySqlCommand())
404 {
405 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = ?EstateID";
406
407 cmd.CommandText = sql;
408 cmd.Parameters.AddWithValue("?EstateID", estateID);
409
410 return DoLoad(cmd, UUID.Zero, false);
411 }
412 }
413
414 public List<int> GetEstates(string search)
415 {
416 List<int> result = new List<int>();
417
418 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
419 {
420 dbcon.Open();
421
422 using (MySqlCommand cmd = dbcon.CreateCommand())
423 {
424 cmd.CommandText = "select estateID from estate_settings where EstateName = ?EstateName";
425 cmd.Parameters.AddWithValue("?EstateName", search);
426
427 using (IDataReader reader = cmd.ExecuteReader())
428 {
429 while (reader.Read())
430 {
431 result.Add(Convert.ToInt32(reader["EstateID"]));
432 }
433 reader.Close();
434 }
435 }
436
437
438 dbcon.Close();
439 }
440
441 return result;
442 }
443
444 public bool LinkRegion(UUID regionID, int estateID)
445 {
446 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
447 {
448 dbcon.Open();
449
450 try
451 {
452 using (MySqlCommand cmd = dbcon.CreateCommand())
453 {
454 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
455 cmd.Parameters.AddWithValue("?RegionID", regionID);
456 cmd.Parameters.AddWithValue("?EstateID", estateID);
457
458 int ret = cmd.ExecuteNonQuery();
459 dbcon.Close();
460
461 return (ret != 0);
462 }
463 }
464 catch (MySqlException ex)
465 {
466 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
467 }
468
469 dbcon.Close();
470 }
471
472 return false;
473 }
474
475 public List<UUID> GetRegions(int estateID)
476 {
477 return new List<UUID>();
478 }
479
480 public bool DeleteEstate(int estateID)
481 {
482 return false;
483 }
401 } 484 }
402} 485}
diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs
new file mode 100644
index 0000000..663fad6
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using MySql.Data.MySqlClient;
35
36namespace OpenSim.Data.MySQL
37{
38 public class MySqlFriendsData : MySQLGenericTableHandler<FriendsData>, IFriendsData
39 {
40 public MySqlFriendsData(string connectionString, string realm)
41 : base(connectionString, realm, "FriendsStore")
42 {
43 }
44
45 public bool Delete(UUID principalID, string friend)
46 {
47 MySqlCommand cmd = new MySqlCommand();
48
49 cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
50 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
51 cmd.Parameters.AddWithValue("?Friend", friend);
52
53 ExecuteNonQuery(cmd);
54
55 return true;
56 }
57
58 public FriendsData[] GetFriends(UUID principalID)
59 {
60 MySqlCommand cmd = new MySqlCommand();
61
62 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
63 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
64
65 return DoQuery(cmd);
66 }
67 }
68}
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
index 7d3593c..1253e0b 100644
--- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
+++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
@@ -95,12 +95,12 @@ namespace OpenSim.Data.MySQL
95 } 95 }
96 } 96 }
97 97
98 public T[] Get(string field, string key) 98 public virtual T[] Get(string field, string key)
99 { 99 {
100 return Get(new string[] { field }, new string[] { key }); 100 return Get(new string[] { field }, new string[] { key });
101 } 101 }
102 102
103 public T[] Get(string[] fields, string[] keys) 103 public virtual T[] Get(string[] fields, string[] keys)
104 { 104 {
105 if (fields.Length != keys.Length) 105 if (fields.Length != keys.Length)
106 return new T[0]; 106 return new T[0];
@@ -194,11 +194,10 @@ namespace OpenSim.Data.MySQL
194 return result.ToArray(); 194 return result.ToArray();
195 } 195 }
196 196
197 public T[] Get(string where) 197 public virtual T[] Get(string where)
198 { 198 {
199 using (MySqlCommand cmd = new MySqlCommand()) 199 using (MySqlCommand cmd = new MySqlCommand())
200 { 200 {
201
202 string query = String.Format("select * from {0} where {1}", 201 string query = String.Format("select * from {0} where {1}",
203 m_Realm, where); 202 m_Realm, where);
204 203
@@ -208,7 +207,7 @@ namespace OpenSim.Data.MySQL
208 } 207 }
209 } 208 }
210 209
211 public bool Store(T row) 210 public virtual bool Store(T row)
212 { 211 {
213 using (MySqlCommand cmd = new MySqlCommand()) 212 using (MySqlCommand cmd = new MySqlCommand())
214 { 213 {
@@ -248,7 +247,7 @@ namespace OpenSim.Data.MySQL
248 } 247 }
249 } 248 }
250 249
251 public bool Delete(string field, string val) 250 public virtual bool Delete(string field, string val)
252 { 251 {
253 using (MySqlCommand cmd = new MySqlCommand()) 252 using (MySqlCommand cmd = new MySqlCommand())
254 { 253 {
diff --git a/OpenSim/Data/MySQL/MySQLGridData.cs b/OpenSim/Data/MySQL/MySQLGridData.cs
deleted file mode 100644
index f4e7b85..0000000
--- a/OpenSim/Data/MySQL/MySQLGridData.cs
+++ /dev/null
@@ -1,422 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using MySql.Data.MySqlClient;
35using OpenMetaverse;
36using OpenSim.Framework;
37
38namespace OpenSim.Data.MySQL
39{
40 /// <summary>
41 /// A MySQL Interface for the Grid Server
42 /// </summary>
43 public class MySQLGridData : GridDataBase
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 private MySQLManager m_database;
48 private object m_dbLock = new object();
49 private string m_connectionString;
50
51 override public void Initialise()
52 {
53 m_log.Info("[MySQLGridData]: " + Name + " cannot be default-initialized!");
54 throw new PluginNotInitialisedException (Name);
55 }
56
57 /// <summary>
58 /// <para>Initialises Grid interface</para>
59 /// <para>
60 /// <list type="bullet">
61 /// <item>Loads and initialises the MySQL storage plugin</item>
62 /// <item>Warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
63 /// <item>Check for migration</item>
64 /// </list>
65 /// </para>
66 /// </summary>
67 /// <param name="connect">connect string.</param>
68 override public void Initialise(string connect)
69 {
70 m_connectionString = connect;
71 m_database = new MySQLManager(connect);
72
73 // This actually does the roll forward assembly stuff
74 Assembly assem = GetType().Assembly;
75
76 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
77 {
78 Migration m = new Migration(dbcon, assem, "GridStore");
79 m.Update();
80 }
81 }
82
83 /// <summary>
84 /// Shuts down the grid interface
85 /// </summary>
86 override public void Dispose()
87 {
88 }
89
90 /// <summary>
91 /// Returns the plugin name
92 /// </summary>
93 /// <returns>Plugin name</returns>
94 override public string Name
95 {
96 get { return "MySql OpenGridData"; }
97 }
98
99 /// <summary>
100 /// Returns the plugin version
101 /// </summary>
102 /// <returns>Plugin version</returns>
103 override public string Version
104 {
105 get { return "0.1"; }
106 }
107
108 /// <summary>
109 /// Returns all the specified region profiles within coordates -- coordinates are inclusive
110 /// </summary>
111 /// <param name="xmin">Minimum X coordinate</param>
112 /// <param name="ymin">Minimum Y coordinate</param>
113 /// <param name="xmax">Maximum X coordinate</param>
114 /// <param name="ymax">Maximum Y coordinate</param>
115 /// <returns>Array of sim profiles</returns>
116 override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax)
117 {
118 try
119 {
120 Dictionary<string, object> param = new Dictionary<string, object>();
121 param["?xmin"] = xmin.ToString();
122 param["?ymin"] = ymin.ToString();
123 param["?xmax"] = xmax.ToString();
124 param["?ymax"] = ymax.ToString();
125
126 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
127 {
128 dbcon.Open();
129
130 using (IDbCommand result = m_database.Query(dbcon,
131 "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax",
132 param))
133 {
134 using (IDataReader reader = result.ExecuteReader())
135 {
136 RegionProfileData row;
137
138 List<RegionProfileData> rows = new List<RegionProfileData>();
139
140 while ((row = m_database.readSimRow(reader)) != null)
141 rows.Add(row);
142
143 return rows.ToArray();
144 }
145 }
146 }
147 }
148 catch (Exception e)
149 {
150 m_log.Error(e.Message, e);
151 return null;
152 }
153 }
154
155 /// <summary>
156 /// Returns up to maxNum profiles of regions that have a name starting with namePrefix
157 /// </summary>
158 /// <param name="name">The name to match against</param>
159 /// <param name="maxNum">Maximum number of profiles to return</param>
160 /// <returns>A list of sim profiles</returns>
161 override public List<RegionProfileData> GetRegionsByName(string namePrefix, uint maxNum)
162 {
163 try
164 {
165 Dictionary<string, object> param = new Dictionary<string, object>();
166 param["?name"] = namePrefix + "%";
167
168 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
169 {
170 dbcon.Open();
171
172 using (IDbCommand result = m_database.Query(dbcon,
173 "SELECT * FROM regions WHERE regionName LIKE ?name",
174 param))
175 {
176 using (IDataReader reader = result.ExecuteReader())
177 {
178 RegionProfileData row;
179
180 List<RegionProfileData> rows = new List<RegionProfileData>();
181
182 while (rows.Count < maxNum && (row = m_database.readSimRow(reader)) != null)
183 rows.Add(row);
184
185 return rows;
186 }
187 }
188 }
189 }
190 catch (Exception e)
191 {
192 m_log.Error(e.Message, e);
193 return null;
194 }
195 }
196
197 /// <summary>
198 /// Returns a sim profile from it's location
199 /// </summary>
200 /// <param name="handle">Region location handle</param>
201 /// <returns>Sim profile</returns>
202 override public RegionProfileData GetProfileByHandle(ulong handle)
203 {
204 try
205 {
206 Dictionary<string, object> param = new Dictionary<string, object>();
207 param["?handle"] = handle.ToString();
208
209 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
210 {
211 dbcon.Open();
212
213 using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE regionHandle = ?handle", param))
214 {
215 using (IDataReader reader = result.ExecuteReader())
216 {
217 RegionProfileData row = m_database.readSimRow(reader);
218 return row;
219 }
220 }
221 }
222 }
223 catch (Exception e)
224 {
225 m_log.Error(e.Message, e);
226 return null;
227 }
228 }
229
230 /// <summary>
231 /// Returns a sim profile from it's UUID
232 /// </summary>
233 /// <param name="uuid">The region UUID</param>
234 /// <returns>The sim profile</returns>
235 override public RegionProfileData GetProfileByUUID(UUID uuid)
236 {
237 try
238 {
239 Dictionary<string, object> param = new Dictionary<string, object>();
240 param["?uuid"] = uuid.ToString();
241
242 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
243 {
244 dbcon.Open();
245
246 using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE uuid = ?uuid", param))
247 {
248 using (IDataReader reader = result.ExecuteReader())
249 {
250 RegionProfileData row = m_database.readSimRow(reader);
251 return row;
252 }
253 }
254 }
255 }
256 catch (Exception e)
257 {
258 m_log.Error(e.Message, e);
259 return null;
260 }
261 }
262
263 /// <summary>
264 /// Returns a sim profile from it's Region name string
265 /// </summary>
266 /// <returns>The sim profile</returns>
267 override public RegionProfileData GetProfileByString(string regionName)
268 {
269 if (regionName.Length > 2)
270 {
271 try
272 {
273 Dictionary<string, object> param = new Dictionary<string, object>();
274 // Add % because this is a like query.
275 param["?regionName"] = regionName + "%";
276
277 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
278 {
279 dbcon.Open();
280
281 // Order by statement will return shorter matches first. Only returns one record or no record.
282 using (IDbCommand result = m_database.Query(dbcon,
283 "SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1",
284 param))
285 {
286 using (IDataReader reader = result.ExecuteReader())
287 {
288 RegionProfileData row = m_database.readSimRow(reader);
289 return row;
290 }
291 }
292 }
293 }
294 catch (Exception e)
295 {
296 m_log.Error(e.Message, e);
297 return null;
298 }
299 }
300
301 m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters");
302 return null;
303 }
304
305 /// <summary>
306 /// Adds a new profile to the database
307 /// </summary>
308 /// <param name="profile">The profile to add</param>
309 /// <returns>Successful?</returns>
310 override public DataResponse StoreProfile(RegionProfileData profile)
311 {
312 try
313 {
314 if (m_database.insertRegion(profile))
315 return DataResponse.RESPONSE_OK;
316 else
317 return DataResponse.RESPONSE_ERROR;
318 }
319 catch
320 {
321 return DataResponse.RESPONSE_ERROR;
322 }
323 }
324
325 /// <summary>
326 /// Deletes a sim profile from the database
327 /// </summary>
328 /// <param name="uuid">the sim UUID</param>
329 /// <returns>Successful?</returns>
330 //public DataResponse DeleteProfile(RegionProfileData profile)
331 override public DataResponse DeleteProfile(string uuid)
332 {
333 try
334 {
335 if (m_database.deleteRegion(uuid))
336 return DataResponse.RESPONSE_OK;
337 else
338 return DataResponse.RESPONSE_ERROR;
339 }
340 catch
341 {
342 return DataResponse.RESPONSE_ERROR;
343 }
344 }
345
346 /// <summary>
347 /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret.
348 /// </summary>
349 /// <param name="uuid">The UUID of the challenger</param>
350 /// <param name="handle">The attempted regionHandle of the challenger</param>
351 /// <param name="authkey">The secret</param>
352 /// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
353 override public bool AuthenticateSim(UUID uuid, ulong handle, string authkey)
354 {
355 bool throwHissyFit = false; // Should be true by 1.0
356
357 if (throwHissyFit)
358 throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
359
360 RegionProfileData data = GetProfileByUUID(uuid);
361
362 return (handle == data.regionHandle && authkey == data.regionSecret);
363 }
364
365 /// <summary>
366 /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
367 /// </summary>
368 /// <remarks>This requires a security audit.</remarks>
369 /// <param name="uuid"></param>
370 /// <param name="handle"></param>
371 /// <param name="authhash"></param>
372 /// <param name="challenge"></param>
373 /// <returns></returns>
374 public bool AuthenticateSim(UUID uuid, ulong handle, string authhash, string challenge)
375 {
376 // SHA512Managed HashProvider = new SHA512Managed();
377 // Encoding TextProvider = new UTF8Encoding();
378
379 // byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
380 // byte[] hash = HashProvider.ComputeHash(stream);
381
382 return false;
383 }
384
385 /// <summary>
386 /// Adds a location reservation
387 /// </summary>
388 /// <param name="x">x coordinate</param>
389 /// <param name="y">y coordinate</param>
390 /// <returns></returns>
391 override public ReservationData GetReservationAtPoint(uint x, uint y)
392 {
393 try
394 {
395 Dictionary<string, object> param = new Dictionary<string, object>();
396 param["?x"] = x.ToString();
397 param["?y"] = y.ToString();
398
399 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
400 {
401 dbcon.Open();
402
403 using (IDbCommand result = m_database.Query(dbcon,
404 "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y",
405 param))
406 {
407 using (IDataReader reader = result.ExecuteReader())
408 {
409 ReservationData row = m_database.readReservationRow(reader);
410 return row;
411 }
412 }
413 }
414 }
415 catch (Exception e)
416 {
417 m_log.Error(e.Message, e);
418 return null;
419 }
420 }
421 }
422}
diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs b/OpenSim/Data/MySQL/MySQLGridUserData.cs
index 2e39cd0..df29ecd 100644
--- a/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs
+++ b/OpenSim/Data/MySQL/MySQLGridUserData.cs
@@ -26,35 +26,39 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
30using System.Collections.Generic; 29using System.Collections.Generic;
31using System.Text; 30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using MySql.Data.MySqlClient;
32 37
33namespace OpenGridServices.Manager 38namespace OpenSim.Data.MySQL
34{ 39{
35 public class BlockingQueue<T> 40 /// <summary>
41 /// A MySQL Interface for user grid data
42 /// </summary>
43 public class MySQLGridUserData : MySQLGenericTableHandler<GridUserData>, IGridUserData
36 { 44 {
37 private Queue<T> _queue = new Queue<T>(); 45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
38 private object _queueSync = new object(); 46
47 public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "UserGrid") {}
39 48
40 public void Enqueue(T value) 49 public GridUserData GetGridUserData(string userID)
41 { 50 {
42 lock (_queueSync) 51 GridUserData[] ret = Get("UserID", userID);
43 { 52
44 _queue.Enqueue(value); 53 if (ret.Length == 0)
45 Monitor.Pulse(_queueSync); 54 return null;
46 } 55
56 return ret[0];
47 } 57 }
48 58
49 public T Dequeue() 59 public bool StoreGridUserData(GridUserData data)
50 { 60 {
51 lock (_queueSync) 61 return Store(data);
52 {
53 if (_queue.Count < 1)
54 Monitor.Wait(_queueSync);
55
56 return _queue.Dequeue();
57 }
58 } 62 }
59 } 63 }
60} 64} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index f84beb6..a395ddc 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -711,9 +711,9 @@ namespace OpenSim.Data.MySQL
711 } 711 }
712 } 712 }
713 713
714 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) 714 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
715 { 715 {
716 RegionMeta7WindlightData nWP = new RegionMeta7WindlightData(); 716 RegionLightShareData nWP = new RegionLightShareData();
717 nWP.OnSave += StoreRegionWindlightSettings; 717 nWP.OnSave += StoreRegionWindlightSettings;
718 718
719 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 719 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
@@ -845,7 +845,7 @@ namespace OpenSim.Data.MySQL
845 return rs; 845 return rs;
846 } 846 }
847 847
848 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) 848 public void StoreRegionWindlightSettings(RegionLightShareData wl)
849 { 849 {
850 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 850 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
851 { 851 {
diff --git a/OpenSim/Data/MySQL/MySQLLogData.cs b/OpenSim/Data/MySQL/MySQLLogData.cs
deleted file mode 100644
index 304883c..0000000
--- a/OpenSim/Data/MySQL/MySQLLogData.cs
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Reflection;
30using log4net;
31using OpenSim.Framework;
32
33namespace OpenSim.Data.MySQL
34{
35 /// <summary>
36 /// An interface to the log database for MySQL
37 /// </summary>
38 internal class MySQLLogData : ILogDataPlugin
39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 /// <summary>
43 /// The database manager
44 /// </summary>
45 public MySQLManager database;
46
47 public void Initialise()
48 {
49 m_log.Info("[MySQLLogData]: " + Name + " cannot be default-initialized!");
50 throw new PluginNotInitialisedException (Name);
51 }
52
53 /// <summary>
54 /// Artificial constructor called when the plugin is loaded
55 /// Uses the obsolete mysql_connection.ini if connect string is empty.
56 /// </summary>
57 /// <param name="connect">connect string</param>
58 public void Initialise(string connect)
59 {
60 if (connect != String.Empty)
61 {
62 database = new MySQLManager(connect);
63 }
64 else
65 {
66 m_log.Warn("Using deprecated mysql_connection.ini. Please update database_connect in GridServer_Config.xml and we'll use that instead");
67
68 IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
69 string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
70 string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
71 string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
72 string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
73 string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
74 string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
75
76 database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword,
77 settingPooling, settingPort);
78 }
79
80 // This actually does the roll forward assembly stuff
81 Assembly assem = GetType().Assembly;
82
83 using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(connect))
84 {
85 dbcon.Open();
86
87 Migration m = new Migration(dbcon, assem, "LogStore");
88
89 // TODO: After rev 6000, remove this. People should have
90 // been rolled onto the new migration code by then.
91 TestTables(m);
92
93 m.Update();
94 }
95 }
96
97 /// <summary></summary>
98 /// <param name="m"></param>
99 private void TestTables(Migration m)
100 {
101 // under migrations, bail
102 if (m.Version > 0)
103 return;
104
105 Dictionary<string, string> tableList = new Dictionary<string, string>();
106 tableList["logs"] = null;
107 database.GetTableVersion(tableList);
108
109 // migrations will handle it
110 if (tableList["logs"] == null)
111 return;
112
113 // we have the table, so pretend like we did the first migration in the past
114 if (m.Version == 0)
115 m.Version = 1;
116 }
117
118 /// <summary>
119 /// Saves a log item to the database
120 /// </summary>
121 /// <param name="serverDaemon">The daemon triggering the event</param>
122 /// <param name="target">The target of the action (region / agent UUID, etc)</param>
123 /// <param name="methodCall">The method call where the problem occured</param>
124 /// <param name="arguments">The arguments passed to the method</param>
125 /// <param name="priority">How critical is this?</param>
126 /// <param name="logMessage">The message to log</param>
127 public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,
128 string logMessage)
129 {
130 try
131 {
132 database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage);
133 }
134 catch
135 {
136 }
137 }
138
139 /// <summary>
140 /// Returns the name of this DB provider
141 /// </summary>
142 /// <returns>A string containing the DB provider name</returns>
143 public string Name
144 {
145 get { return "MySQL Logdata Interface";}
146 }
147
148 /// <summary>
149 /// Closes the database provider
150 /// </summary>
151 /// <remarks>do nothing</remarks>
152 public void Dispose()
153 {
154 // Do nothing.
155 }
156
157 /// <summary>
158 /// Returns the version of this DB provider
159 /// </summary>
160 /// <returns>A string containing the provider version</returns>
161 public string Version
162 {
163 get { return "0.1"; }
164 }
165 }
166}
diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs
deleted file mode 100644
index ace2027..0000000
--- a/OpenSim/Data/MySQL/MySQLManager.cs
+++ /dev/null
@@ -1,1248 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using System.IO;
33using System.Reflection;
34using log4net;
35using MySql.Data.MySqlClient;
36using OpenMetaverse;
37using OpenSim.Framework;
38
39namespace OpenSim.Data.MySQL
40{
41 /// <summary>
42 /// A MySQL Database manager
43 /// </summary>
44 public class MySQLManager
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 /// <summary>
49 /// Connection string for ADO.net
50 /// </summary>
51 private string connectionString;
52
53 private object m_dbLock = new object();
54
55 private const string m_waitTimeoutSelect = "select @@wait_timeout";
56
57 /// <summary>
58 /// Wait timeout for our connection in ticks.
59 /// </summary>
60 private long m_waitTimeout;
61
62 /// <summary>
63 /// Make our storage of the timeout this amount smaller than it actually is, to give us a margin on long
64 /// running database operations.
65 /// </summary>
66 private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
67
68 /// <summary>
69 /// Holds the last tick time that the connection was used.
70 /// </summary>
71 private long m_lastConnectionUse;
72
73 /// <summary>
74 /// Initialises and creates a new MySQL connection and maintains it.
75 /// </summary>
76 /// <param name="hostname">The MySQL server being connected to</param>
77 /// <param name="database">The name of the MySQL database being used</param>
78 /// <param name="username">The username logging into the database</param>
79 /// <param name="password">The password for the user logging in</param>
80 /// <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>
81 /// <param name="port">The MySQL server port</param>
82 public MySQLManager(string hostname, string database, string username, string password, string cpooling,
83 string port)
84 {
85 string s = "Server=" + hostname + ";Port=" + port + ";Database=" + database + ";User ID=" +
86 username + ";Password=" + password + ";Pooling=" + cpooling + ";";
87
88 Initialise(s);
89 }
90
91 /// <summary>
92 /// Initialises and creates a new MySQL connection and maintains it.
93 /// </summary>
94 /// <param name="connect">connectionString</param>
95 public MySQLManager(String connect)
96 {
97 Initialise(connect);
98 }
99
100 /// <summary>
101 /// Initialises and creates a new MySQL connection and maintains it.
102 /// </summary>
103 /// <param name="connect">connectionString</param>
104 public void Initialise(String connect)
105 {
106 try
107 {
108 connectionString = connect;
109 //dbcon = new MySqlConnection(connectionString);
110
111 try
112 {
113 //dbcon.Open();
114 }
115 catch(Exception e)
116 {
117 throw new Exception("Connection error while using connection string ["+connectionString+"]", e);
118 }
119
120 m_log.Info("[MYSQL]: Connection established");
121 GetWaitTimeout();
122 }
123 catch (Exception e)
124 {
125 throw new Exception("Error initialising MySql Database: " + e.ToString());
126 }
127 }
128
129 /// <summary>
130 /// Get the wait_timeout value for our connection
131 /// </summary>
132 protected void GetWaitTimeout()
133 {
134 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
135 {
136 dbcon.Open();
137
138 using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon))
139 {
140 using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
141 {
142 if (dbReader.Read())
143 {
144 m_waitTimeout
145 = Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway;
146 }
147 }
148 }
149 }
150
151 m_lastConnectionUse = DateTime.Now.Ticks;
152
153 m_log.DebugFormat(
154 "[REGION DB]: Connection wait timeout {0} seconds", m_waitTimeout / TimeSpan.TicksPerSecond);
155 }
156
157 public string ConnectionString
158 {
159 get { return connectionString; }
160 }
161
162 /// <summary>
163 /// Returns the version of this DB provider
164 /// </summary>
165 /// <returns>A string containing the DB provider</returns>
166 public string getVersion()
167 {
168 Module module = GetType().Module;
169 // string dllName = module.Assembly.ManifestModule.Name;
170 Version dllVersion = module.Assembly.GetName().Version;
171
172 return
173 string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
174 dllVersion.Revision);
175 }
176
177 /// <summary>
178 /// Extract a named string resource from the embedded resources
179 /// </summary>
180 /// <param name="name">name of embedded resource</param>
181 /// <returns>string contained within the embedded resource</returns>
182 private string getResourceString(string name)
183 {
184 Assembly assem = GetType().Assembly;
185 string[] names = assem.GetManifestResourceNames();
186
187 foreach (string s in names)
188 {
189 if (s.EndsWith(name))
190 {
191 using (Stream resource = assem.GetManifestResourceStream(s))
192 {
193 using (StreamReader resourceReader = new StreamReader(resource))
194 {
195 string resourceString = resourceReader.ReadToEnd();
196 return resourceString;
197 }
198 }
199 }
200 }
201 throw new Exception(string.Format("Resource '{0}' was not found", name));
202 }
203
204 /// <summary>
205 /// Execute a SQL statement stored in a resource, as a string
206 /// </summary>
207 /// <param name="name">name of embedded resource</param>
208 public void ExecuteResourceSql(string name)
209 {
210 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
211 {
212 dbcon.Open();
213
214 MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon);
215 cmd.ExecuteNonQuery();
216 }
217 }
218
219 /// <summary>
220 /// Execute a MySqlCommand
221 /// </summary>
222 /// <param name="sql">sql string to execute</param>
223 public void ExecuteSql(string sql)
224 {
225 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
226 {
227 dbcon.Open();
228
229 MySqlCommand cmd = new MySqlCommand(sql, dbcon);
230 cmd.ExecuteNonQuery();
231 }
232 }
233
234 public void ExecuteParameterizedSql(string sql, Dictionary<string, string> parameters)
235 {
236 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
237 {
238 dbcon.Open();
239
240 MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand();
241 cmd.CommandText = sql;
242 foreach (KeyValuePair<string, string> param in parameters)
243 {
244 cmd.Parameters.AddWithValue(param.Key, param.Value);
245 }
246 cmd.ExecuteNonQuery();
247 }
248 }
249
250 /// <summary>
251 /// Given a list of tables, return the version of the tables, as seen in the database
252 /// </summary>
253 /// <param name="tableList"></param>
254 public void GetTableVersion(Dictionary<string, string> tableList)
255 {
256 lock (m_dbLock)
257 {
258 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
259 {
260 dbcon.Open();
261
262 using (MySqlCommand tablesCmd = new MySqlCommand(
263 "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", dbcon))
264 {
265 tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database);
266
267 using (MySqlDataReader tables = tablesCmd.ExecuteReader())
268 {
269 while (tables.Read())
270 {
271 try
272 {
273 string tableName = (string)tables["TABLE_NAME"];
274 string comment = (string)tables["TABLE_COMMENT"];
275 if (tableList.ContainsKey(tableName))
276 {
277 tableList[tableName] = comment;
278 }
279 }
280 catch (Exception e)
281 {
282 m_log.Error(e.Message, e);
283 }
284 }
285 }
286 }
287 }
288 }
289 }
290
291 // TODO: at some time this code should be cleaned up
292
293 /// <summary>
294 /// Runs a query with protection against SQL Injection by using parameterised input.
295 /// </summary>
296 /// <param name="dbcon">Database connection</param>
297 /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
298 /// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
299 /// <returns>A MySQL DB Command</returns>
300 public IDbCommand Query(MySqlConnection dbcon, string sql, Dictionary<string, object> parameters)
301 {
302 try
303 {
304 MySqlCommand dbcommand = (MySqlCommand)dbcon.CreateCommand();
305 dbcommand.CommandText = sql;
306 foreach (KeyValuePair<string, object> param in parameters)
307 {
308 dbcommand.Parameters.AddWithValue(param.Key, param.Value);
309 }
310
311 return (IDbCommand)dbcommand;
312 }
313 catch (Exception e)
314 {
315 // Return null if it fails.
316 m_log.Error("Failed during Query generation: " + e.Message, e);
317 return null;
318 }
319 }
320
321 /// <summary>
322 /// Reads a region row from a database reader
323 /// </summary>
324 /// <param name="reader">An active database reader</param>
325 /// <returns>A region profile</returns>
326 public RegionProfileData readSimRow(IDataReader reader)
327 {
328 RegionProfileData retval = new RegionProfileData();
329
330 if (reader.Read())
331 {
332 // Region Main gotta-have-or-we-return-null parts
333 UInt64 tmp64;
334 if (!UInt64.TryParse(reader["regionHandle"].ToString(), out tmp64))
335 {
336 return null;
337 }
338 else
339 {
340 retval.regionHandle = tmp64;
341 }
342 UUID tmp_uuid;
343 if (!UUID.TryParse((string)reader["uuid"], out tmp_uuid))
344 {
345 return null;
346 }
347 else
348 {
349 retval.UUID = tmp_uuid;
350 }
351
352 // non-critical parts
353 retval.regionName = (string)reader["regionName"];
354 retval.originUUID = new UUID((string) reader["originUUID"]);
355
356 // Secrets
357 retval.regionRecvKey = (string) reader["regionRecvKey"];
358 retval.regionSecret = (string) reader["regionSecret"];
359 retval.regionSendKey = (string) reader["regionSendKey"];
360
361 // Region Server
362 retval.regionDataURI = (string) reader["regionDataURI"];
363 retval.regionOnline = false; // Needs to be pinged before this can be set.
364 retval.serverIP = (string) reader["serverIP"];
365 retval.serverPort = (uint) reader["serverPort"];
366 retval.serverURI = (string) reader["serverURI"];
367 retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString());
368 retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString());
369
370 // Location
371 retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString());
372 retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString());
373 retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString());
374
375 // Neighbours - 0 = No Override
376 retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString());
377 retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString());
378 retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString());
379 retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString());
380
381 // Assets
382 retval.regionAssetURI = (string) reader["regionAssetURI"];
383 retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"];
384 retval.regionAssetSendKey = (string) reader["regionAssetSendKey"];
385
386 // Userserver
387 retval.regionUserURI = (string) reader["regionUserURI"];
388 retval.regionUserRecvKey = (string) reader["regionUserRecvKey"];
389 retval.regionUserSendKey = (string) reader["regionUserSendKey"];
390
391 // World Map Addition
392 UUID.TryParse((string)reader["regionMapTexture"], out retval.regionMapTextureID);
393 UUID.TryParse((string)reader["owner_uuid"], out retval.owner_uuid);
394 retval.maturity = Convert.ToUInt32(reader["access"]);
395 }
396 else
397 {
398 return null;
399 }
400 return retval;
401 }
402
403 /// <summary>
404 /// Reads a reservation row from a database reader
405 /// </summary>
406 /// <param name="reader">An active database reader</param>
407 /// <returns>A reservation data object</returns>
408 public ReservationData readReservationRow(IDataReader reader)
409 {
410 ReservationData retval = new ReservationData();
411 if (reader.Read())
412 {
413 retval.gridRecvKey = (string) reader["gridRecvKey"];
414 retval.gridSendKey = (string) reader["gridSendKey"];
415 retval.reservationCompany = (string) reader["resCompany"];
416 retval.reservationMaxX = Convert.ToInt32(reader["resXMax"].ToString());
417 retval.reservationMaxY = Convert.ToInt32(reader["resYMax"].ToString());
418 retval.reservationMinX = Convert.ToInt32(reader["resXMin"].ToString());
419 retval.reservationMinY = Convert.ToInt32(reader["resYMin"].ToString());
420 retval.reservationName = (string) reader["resName"];
421 retval.status = Convert.ToInt32(reader["status"].ToString()) == 1;
422 UUID tmp;
423 UUID.TryParse((string) reader["userUUID"], out tmp);
424 retval.userUUID = tmp;
425 }
426 else
427 {
428 return null;
429 }
430 return retval;
431 }
432
433 /// <summary>
434 /// Reads an agent row from a database reader
435 /// </summary>
436 /// <param name="reader">An active database reader</param>
437 /// <returns>A user session agent</returns>
438 public UserAgentData readAgentRow(IDataReader reader)
439 {
440 UserAgentData retval = new UserAgentData();
441
442 if (reader.Read())
443 {
444 // Agent IDs
445 UUID tmp;
446 if (!UUID.TryParse((string)reader["UUID"], out tmp))
447 return null;
448 retval.ProfileID = tmp;
449
450 UUID.TryParse((string) reader["sessionID"], out tmp);
451 retval.SessionID = tmp;
452
453 UUID.TryParse((string)reader["secureSessionID"], out tmp);
454 retval.SecureSessionID = tmp;
455
456 // Agent Who?
457 retval.AgentIP = (string) reader["agentIP"];
458 retval.AgentPort = Convert.ToUInt32(reader["agentPort"].ToString());
459 retval.AgentOnline = Convert.ToBoolean(Convert.ToInt16(reader["agentOnline"].ToString()));
460
461 // Login/Logout times (UNIX Epoch)
462 retval.LoginTime = Convert.ToInt32(reader["loginTime"].ToString());
463 retval.LogoutTime = Convert.ToInt32(reader["logoutTime"].ToString());
464
465 // Current position
466 retval.Region = new UUID((string)reader["currentRegion"]);
467 retval.Handle = Convert.ToUInt64(reader["currentHandle"].ToString());
468 Vector3 tmp_v;
469 Vector3.TryParse((string) reader["currentPos"], out tmp_v);
470 retval.Position = tmp_v;
471 Vector3.TryParse((string)reader["currentLookAt"], out tmp_v);
472 retval.LookAt = tmp_v;
473 }
474 else
475 {
476 return null;
477 }
478 return retval;
479 }
480
481 /// <summary>
482 /// Reads a user profile from an active data reader
483 /// </summary>
484 /// <param name="reader">An active database reader</param>
485 /// <returns>A user profile</returns>
486 public UserProfileData readUserRow(IDataReader reader)
487 {
488 UserProfileData retval = new UserProfileData();
489
490 if (reader.Read())
491 {
492 UUID id;
493 if (!UUID.TryParse((string)reader["UUID"], out id))
494 return null;
495
496 retval.ID = id;
497 retval.FirstName = (string) reader["username"];
498 retval.SurName = (string) reader["lastname"];
499 retval.Email = (reader.IsDBNull(reader.GetOrdinal("email"))) ? "" : (string) reader["email"];
500
501 retval.PasswordHash = (string) reader["passwordHash"];
502 retval.PasswordSalt = (string) reader["passwordSalt"];
503
504 retval.HomeRegion = Convert.ToUInt64(reader["homeRegion"].ToString());
505 retval.HomeLocation = new Vector3(
506 Convert.ToSingle(reader["homeLocationX"].ToString()),
507 Convert.ToSingle(reader["homeLocationY"].ToString()),
508 Convert.ToSingle(reader["homeLocationZ"].ToString()));
509 retval.HomeLookAt = new Vector3(
510 Convert.ToSingle(reader["homeLookAtX"].ToString()),
511 Convert.ToSingle(reader["homeLookAtY"].ToString()),
512 Convert.ToSingle(reader["homeLookAtZ"].ToString()));
513
514 UUID regionID = UUID.Zero;
515 UUID.TryParse(reader["homeRegionID"].ToString(), out regionID); // it's ok if it doesn't work; just use UUID.Zero
516 retval.HomeRegionID = regionID;
517
518 retval.Created = Convert.ToInt32(reader["created"].ToString());
519 retval.LastLogin = Convert.ToInt32(reader["lastLogin"].ToString());
520
521 retval.UserInventoryURI = (string) reader["userInventoryURI"];
522 retval.UserAssetURI = (string) reader["userAssetURI"];
523
524 retval.CanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString());
525 retval.WantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString());
526
527 if (reader.IsDBNull(reader.GetOrdinal("profileAboutText")))
528 retval.AboutText = "";
529 else
530 retval.AboutText = (string) reader["profileAboutText"];
531
532 if (reader.IsDBNull(reader.GetOrdinal("profileFirstText")))
533 retval.FirstLifeAboutText = "";
534 else
535 retval.FirstLifeAboutText = (string)reader["profileFirstText"];
536
537 if (reader.IsDBNull(reader.GetOrdinal("profileImage")))
538 retval.Image = UUID.Zero;
539 else {
540 UUID tmp;
541 UUID.TryParse((string)reader["profileImage"], out tmp);
542 retval.Image = tmp;
543 }
544
545 if (reader.IsDBNull(reader.GetOrdinal("profileFirstImage")))
546 retval.FirstLifeImage = UUID.Zero;
547 else {
548 UUID tmp;
549 UUID.TryParse((string)reader["profileFirstImage"], out tmp);
550 retval.FirstLifeImage = tmp;
551 }
552
553 if (reader.IsDBNull(reader.GetOrdinal("webLoginKey")))
554 {
555 retval.WebLoginKey = UUID.Zero;
556 }
557 else
558 {
559 UUID tmp;
560 UUID.TryParse((string)reader["webLoginKey"], out tmp);
561 retval.WebLoginKey = tmp;
562 }
563
564 retval.UserFlags = Convert.ToInt32(reader["userFlags"].ToString());
565 retval.GodLevel = Convert.ToInt32(reader["godLevel"].ToString());
566 if (reader.IsDBNull(reader.GetOrdinal("customType")))
567 retval.CustomType = "";
568 else
569 retval.CustomType = reader["customType"].ToString();
570
571 if (reader.IsDBNull(reader.GetOrdinal("partner")))
572 {
573 retval.Partner = UUID.Zero;
574 }
575 else
576 {
577 UUID tmp;
578 UUID.TryParse((string)reader["partner"], out tmp);
579 retval.Partner = tmp;
580 }
581 }
582 else
583 {
584 return null;
585 }
586 return retval;
587 }
588
589 /// <summary>
590 /// Reads an avatar appearence from an active data reader
591 /// </summary>
592 /// <param name="reader">An active database reader</param>
593 /// <returns>An avatar appearence</returns>
594 public AvatarAppearance readAppearanceRow(IDataReader reader)
595 {
596 AvatarAppearance appearance = null;
597 if (reader.Read())
598 {
599 appearance = new AvatarAppearance();
600 appearance.Owner = new UUID((string)reader["owner"]);
601 appearance.Serial = Convert.ToInt32(reader["serial"]);
602 appearance.VisualParams = (byte[])reader["visual_params"];
603 appearance.Texture = new Primitive.TextureEntry((byte[])reader["texture"], 0, ((byte[])reader["texture"]).Length);
604 appearance.AvatarHeight = (float)Convert.ToDouble(reader["avatar_height"]);
605 appearance.BodyItem = new UUID((string)reader["body_item"]);
606 appearance.BodyAsset = new UUID((string)reader["body_asset"]);
607 appearance.SkinItem = new UUID((string)reader["skin_item"]);
608 appearance.SkinAsset = new UUID((string)reader["skin_asset"]);
609 appearance.HairItem = new UUID((string)reader["hair_item"]);
610 appearance.HairAsset = new UUID((string)reader["hair_asset"]);
611 appearance.EyesItem = new UUID((string)reader["eyes_item"]);
612 appearance.EyesAsset = new UUID((string)reader["eyes_asset"]);
613 appearance.ShirtItem = new UUID((string)reader["shirt_item"]);
614 appearance.ShirtAsset = new UUID((string)reader["shirt_asset"]);
615 appearance.PantsItem = new UUID((string)reader["pants_item"]);
616 appearance.PantsAsset = new UUID((string)reader["pants_asset"]);
617 appearance.ShoesItem = new UUID((string)reader["shoes_item"]);
618 appearance.ShoesAsset = new UUID((string)reader["shoes_asset"]);
619 appearance.SocksItem = new UUID((string)reader["socks_item"]);
620 appearance.SocksAsset = new UUID((string)reader["socks_asset"]);
621 appearance.JacketItem = new UUID((string)reader["jacket_item"]);
622 appearance.JacketAsset = new UUID((string)reader["jacket_asset"]);
623 appearance.GlovesItem = new UUID((string)reader["gloves_item"]);
624 appearance.GlovesAsset = new UUID((string)reader["gloves_asset"]);
625 appearance.UnderShirtItem = new UUID((string)reader["undershirt_item"]);
626 appearance.UnderShirtAsset = new UUID((string)reader["undershirt_asset"]);
627 appearance.UnderPantsItem = new UUID((string)reader["underpants_item"]);
628 appearance.UnderPantsAsset = new UUID((string)reader["underpants_asset"]);
629 appearance.SkirtItem = new UUID((string)reader["skirt_item"]);
630 appearance.SkirtAsset = new UUID((string)reader["skirt_asset"]);
631 }
632 return appearance;
633 }
634
635 // Read attachment list from data reader
636 public Hashtable readAttachments(IDataReader r)
637 {
638 Hashtable ret = new Hashtable();
639
640 while (r.Read())
641 {
642 int attachpoint = Convert.ToInt32(r["attachpoint"]);
643 if (ret.ContainsKey(attachpoint))
644 continue;
645 Hashtable item = new Hashtable();
646 item.Add("item", r["item"].ToString());
647 item.Add("asset", r["asset"].ToString());
648
649 ret.Add(attachpoint, item);
650 }
651
652 return ret;
653 }
654
655 /// <summary>
656 /// Inserts a new row into the log database
657 /// </summary>
658 /// <param name="serverDaemon">The daemon which triggered this event</param>
659 /// <param name="target">Who were we operating on when this occured (region UUID, user UUID, etc)</param>
660 /// <param name="methodCall">The method call where the problem occured</param>
661 /// <param name="arguments">The arguments passed to the method</param>
662 /// <param name="priority">How critical is this?</param>
663 /// <param name="logMessage">Extra message info</param>
664 /// <returns>Saved successfully?</returns>
665 public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority,
666 string logMessage)
667 {
668 string sql = "INSERT INTO logs (`target`, `server`, `method`, `arguments`, `priority`, `message`) VALUES ";
669 sql += "(?target, ?server, ?method, ?arguments, ?priority, ?message)";
670
671 Dictionary<string, object> parameters = new Dictionary<string, object>();
672 parameters["?server"] = serverDaemon;
673 parameters["?target"] = target;
674 parameters["?method"] = methodCall;
675 parameters["?arguments"] = arguments;
676 parameters["?priority"] = priority.ToString();
677 parameters["?message"] = logMessage;
678
679 bool returnval = false;
680
681 try
682 {
683 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
684 {
685 dbcon.Open();
686
687 IDbCommand result = Query(dbcon, sql, parameters);
688
689 if (result.ExecuteNonQuery() == 1)
690 returnval = true;
691
692 result.Dispose();
693 }
694 }
695 catch (Exception e)
696 {
697 m_log.Error(e.ToString());
698 return false;
699 }
700
701 return returnval;
702 }
703
704 /// <summary>
705 /// Creates a new user and inserts it into the database
706 /// </summary>
707 /// <param name="uuid">User ID</param>
708 /// <param name="username">First part of the login</param>
709 /// <param name="lastname">Second part of the login</param>
710 /// <param name="passwordHash">A salted hash of the users password</param>
711 /// <param name="passwordSalt">The salt used for the password hash</param>
712 /// <param name="homeRegion">A regionHandle of the users home region</param>
713 /// <param name="homeRegionID"> The UUID of the user's home region</param>
714 /// <param name="homeLocX">Home region position vector</param>
715 /// <param name="homeLocY">Home region position vector</param>
716 /// <param name="homeLocZ">Home region position vector</param>
717 /// <param name="homeLookAtX">Home region 'look at' vector</param>
718 /// <param name="homeLookAtY">Home region 'look at' vector</param>
719 /// <param name="homeLookAtZ">Home region 'look at' vector</param>
720 /// <param name="created">Account created (unix timestamp)</param>
721 /// <param name="lastlogin">Last login (unix timestamp)</param>
722 /// <param name="inventoryURI">Users inventory URI</param>
723 /// <param name="assetURI">Users asset URI</param>
724 /// <param name="canDoMask">I can do mask</param>
725 /// <param name="wantDoMask">I want to do mask</param>
726 /// <param name="aboutText">Profile text</param>
727 /// <param name="firstText">Firstlife text</param>
728 /// <param name="profileImage">UUID for profile image</param>
729 /// <param name="firstImage">UUID for firstlife image</param>
730 /// <param name="webLoginKey">Ignored</param>
731 /// <returns>Success?</returns>
732 public bool insertUserRow(UUID uuid, string username, string lastname, string email, string passwordHash,
733 string passwordSalt, UInt64 homeRegion, UUID homeRegionID, float homeLocX, float homeLocY, float homeLocZ,
734 float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
735 string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
736 string aboutText, string firstText,
737 UUID profileImage, UUID firstImage, UUID webLoginKey, int userFlags, int godLevel, string customType, UUID partner)
738 {
739 m_log.Debug("[MySQLManager]: Creating profile for \"" + username + " " + lastname + "\" (" + uuid + ")");
740 string sql =
741 "INSERT INTO users (`UUID`, `username`, `lastname`, `email`, `passwordHash`, `passwordSalt`, `homeRegion`, `homeRegionID`, ";
742 sql +=
743 "`homeLocationX`, `homeLocationY`, `homeLocationZ`, `homeLookAtX`, `homeLookAtY`, `homeLookAtZ`, `created`, ";
744 sql +=
745 "`lastLogin`, `userInventoryURI`, `userAssetURI`, `profileCanDoMask`, `profileWantDoMask`, `profileAboutText`, ";
746 sql += "`profileFirstText`, `profileImage`, `profileFirstImage`, `webLoginKey`, `userFlags`, `godLevel`, `customType`, `partner`) VALUES ";
747
748 sql += "(?UUID, ?username, ?lastname, ?email, ?passwordHash, ?passwordSalt, ?homeRegion, ?homeRegionID, ";
749 sql +=
750 "?homeLocationX, ?homeLocationY, ?homeLocationZ, ?homeLookAtX, ?homeLookAtY, ?homeLookAtZ, ?created, ";
751 sql +=
752 "?lastLogin, ?userInventoryURI, ?userAssetURI, ?profileCanDoMask, ?profileWantDoMask, ?profileAboutText, ";
753 sql += "?profileFirstText, ?profileImage, ?profileFirstImage, ?webLoginKey, ?userFlags, ?godLevel, ?customType, ?partner)";
754
755 Dictionary<string, object> parameters = new Dictionary<string, object>();
756 parameters["?UUID"] = uuid.ToString();
757 parameters["?username"] = username;
758 parameters["?lastname"] = lastname;
759 parameters["?email"] = email;
760 parameters["?passwordHash"] = passwordHash;
761 parameters["?passwordSalt"] = passwordSalt;
762 parameters["?homeRegion"] = homeRegion;
763 parameters["?homeRegionID"] = homeRegionID.ToString();
764 parameters["?homeLocationX"] = homeLocX;
765 parameters["?homeLocationY"] = homeLocY;
766 parameters["?homeLocationZ"] = homeLocZ;
767 parameters["?homeLookAtX"] = homeLookAtX;
768 parameters["?homeLookAtY"] = homeLookAtY;
769 parameters["?homeLookAtZ"] = homeLookAtZ;
770 parameters["?created"] = created;
771 parameters["?lastLogin"] = lastlogin;
772 parameters["?userInventoryURI"] = inventoryURI;
773 parameters["?userAssetURI"] = assetURI;
774 parameters["?profileCanDoMask"] = canDoMask;
775 parameters["?profileWantDoMask"] = wantDoMask;
776 parameters["?profileAboutText"] = aboutText;
777 parameters["?profileFirstText"] = firstText;
778 parameters["?profileImage"] = profileImage.ToString();
779 parameters["?profileFirstImage"] = firstImage.ToString();
780 parameters["?webLoginKey"] = webLoginKey.ToString();
781 parameters["?userFlags"] = userFlags;
782 parameters["?godLevel"] = godLevel;
783 parameters["?customType"] = customType == null ? "" : customType;
784 parameters["?partner"] = partner.ToString();
785 bool returnval = false;
786
787 try
788 {
789 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
790 {
791 dbcon.Open();
792
793 IDbCommand result = Query(dbcon, sql, parameters);
794
795 if (result.ExecuteNonQuery() == 1)
796 returnval = true;
797
798 result.Dispose();
799 }
800 }
801 catch (Exception e)
802 {
803 m_log.Error(e.ToString());
804 return false;
805 }
806
807 //m_log.Debug("[MySQLManager]: Fetch user retval == " + returnval.ToString());
808 return returnval;
809 }
810
811 /// <summary>
812 /// Update user data into the database where User ID = uuid
813 /// </summary>
814 /// <param name="uuid">User ID</param>
815 /// <param name="username">First part of the login</param>
816 /// <param name="lastname">Second part of the login</param>
817 /// <param name="passwordHash">A salted hash of the users password</param>
818 /// <param name="passwordSalt">The salt used for the password hash</param>
819 /// <param name="homeRegion">A regionHandle of the users home region</param>
820 /// <param name="homeLocX">Home region position vector</param>
821 /// <param name="homeLocY">Home region position vector</param>
822 /// <param name="homeLocZ">Home region position vector</param>
823 /// <param name="homeLookAtX">Home region 'look at' vector</param>
824 /// <param name="homeLookAtY">Home region 'look at' vector</param>
825 /// <param name="homeLookAtZ">Home region 'look at' vector</param>
826 /// <param name="created">Account created (unix timestamp)</param>
827 /// <param name="lastlogin">Last login (unix timestamp)</param>
828 /// <param name="inventoryURI">Users inventory URI</param>
829 /// <param name="assetURI">Users asset URI</param>
830 /// <param name="canDoMask">I can do mask</param>
831 /// <param name="wantDoMask">I want to do mask</param>
832 /// <param name="aboutText">Profile text</param>
833 /// <param name="firstText">Firstlife text</param>
834 /// <param name="profileImage">UUID for profile image</param>
835 /// <param name="firstImage">UUID for firstlife image</param>
836 /// <param name="webLoginKey">UUID for weblogin Key</param>
837 /// <returns>Success?</returns>
838 public bool updateUserRow(UUID uuid, string username, string lastname, string email, string passwordHash,
839 string passwordSalt, UInt64 homeRegion, UUID homeRegionID, float homeLocX, float homeLocY, float homeLocZ,
840 float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
841 string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
842 string aboutText, string firstText,
843 UUID profileImage, UUID firstImage, UUID webLoginKey, int userFlags, int godLevel, string customType, UUID partner)
844 {
845 string sql = "UPDATE users SET `username` = ?username , `lastname` = ?lastname, `email` = ?email ";
846 sql += ", `passwordHash` = ?passwordHash , `passwordSalt` = ?passwordSalt , ";
847 sql += "`homeRegion` = ?homeRegion , `homeRegionID` = ?homeRegionID, `homeLocationX` = ?homeLocationX , ";
848 sql += "`homeLocationY` = ?homeLocationY , `homeLocationZ` = ?homeLocationZ , ";
849 sql += "`homeLookAtX` = ?homeLookAtX , `homeLookAtY` = ?homeLookAtY , ";
850 sql += "`homeLookAtZ` = ?homeLookAtZ , `created` = ?created , `lastLogin` = ?lastLogin , ";
851 sql += "`userInventoryURI` = ?userInventoryURI , `userAssetURI` = ?userAssetURI , ";
852 sql += "`profileCanDoMask` = ?profileCanDoMask , `profileWantDoMask` = ?profileWantDoMask , ";
853 sql += "`profileAboutText` = ?profileAboutText , `profileFirstText` = ?profileFirstText, ";
854 sql += "`profileImage` = ?profileImage , `profileFirstImage` = ?profileFirstImage , ";
855 sql += "`userFlags` = ?userFlags , `godLevel` = ?godLevel , ";
856 sql += "`customType` = ?customType , `partner` = ?partner , ";
857 sql += "`webLoginKey` = ?webLoginKey WHERE UUID = ?UUID";
858
859 Dictionary<string, object> parameters = new Dictionary<string, object>();
860 parameters["?UUID"] = uuid.ToString();
861 parameters["?username"] = username;
862 parameters["?lastname"] = lastname;
863 parameters["?email"] = email;
864 parameters["?passwordHash"] = passwordHash;
865 parameters["?passwordSalt"] = passwordSalt;
866 parameters["?homeRegion"] = homeRegion;
867 parameters["?homeRegionID"] = homeRegionID.ToString();
868 parameters["?homeLocationX"] = homeLocX;
869 parameters["?homeLocationY"] = homeLocY;
870 parameters["?homeLocationZ"] = homeLocZ;
871 parameters["?homeLookAtX"] = homeLookAtX;
872 parameters["?homeLookAtY"] = homeLookAtY;
873 parameters["?homeLookAtZ"] = homeLookAtZ;
874 parameters["?created"] = created;
875 parameters["?lastLogin"] = lastlogin;
876 parameters["?userInventoryURI"] = inventoryURI;
877 parameters["?userAssetURI"] = assetURI;
878 parameters["?profileCanDoMask"] = canDoMask;
879 parameters["?profileWantDoMask"] = wantDoMask;
880 parameters["?profileAboutText"] = aboutText;
881 parameters["?profileFirstText"] = firstText;
882 parameters["?profileImage"] = profileImage.ToString();
883 parameters["?profileFirstImage"] = firstImage.ToString();
884 parameters["?webLoginKey"] = webLoginKey.ToString();
885 parameters["?userFlags"] = userFlags;
886 parameters["?godLevel"] = godLevel;
887 parameters["?customType"] = customType == null ? "" : customType;
888 parameters["?partner"] = partner.ToString();
889
890 bool returnval = false;
891 try
892 {
893 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
894 {
895 dbcon.Open();
896
897 IDbCommand result = Query(dbcon, sql, parameters);
898
899 if (result.ExecuteNonQuery() == 1)
900 returnval = true;
901
902 result.Dispose();
903 }
904 }
905 catch (Exception e)
906 {
907 m_log.Error(e.ToString());
908 return false;
909 }
910
911 //m_log.Debug("[MySQLManager]: update user retval == " + returnval.ToString());
912 return returnval;
913 }
914
915 /// <summary>
916 /// Inserts a new region into the database
917 /// </summary>
918 /// <param name="regiondata">The region to insert</param>
919 /// <returns>Success?</returns>
920 public bool insertRegion(RegionProfileData regiondata)
921 {
922 bool GRID_ONLY_UPDATE_NECESSARY_DATA = false;
923
924 string sql = String.Empty;
925 if (GRID_ONLY_UPDATE_NECESSARY_DATA)
926 {
927 sql += "INSERT INTO ";
928 }
929 else
930 {
931 sql += "REPLACE INTO ";
932 }
933
934 sql += "regions (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, ";
935 sql +=
936 "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, ";
937
938 // part of an initial brutish effort to provide accurate information (as per the xml region spec)
939 // wrt the ownership of a given region
940 // the (very bad) assumption is that this value is being read and handled inconsistently or
941 // not at all. Current strategy is to put the code in place to support the validity of this information
942 // and to roll forward debugging any issues from that point
943 //
944 // this particular section of the mod attempts to implement the commit of a supplied value
945 // 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,
946 // as well as the related parameterization
947 sql +=
948 "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid, originUUID, access) VALUES ";
949
950 sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, ";
951 sql +=
952 "?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, ";
953 sql +=
954 "?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid, ?originUUID, ?access)";
955
956 if (GRID_ONLY_UPDATE_NECESSARY_DATA)
957 {
958 sql += "ON DUPLICATE KEY UPDATE serverIP = ?serverIP, serverPort = ?serverPort, serverURI = ?serverURI, owner_uuid - ?owner_uuid;";
959 }
960 else
961 {
962 sql += ";";
963 }
964
965 Dictionary<string, object> parameters = new Dictionary<string, object>();
966
967 parameters["?regionHandle"] = regiondata.regionHandle.ToString();
968 parameters["?regionName"] = regiondata.regionName.ToString();
969 parameters["?uuid"] = regiondata.UUID.ToString();
970 parameters["?regionRecvKey"] = regiondata.regionRecvKey.ToString();
971 parameters["?regionSecret"] = regiondata.regionSecret.ToString();
972 parameters["?regionSendKey"] = regiondata.regionSendKey.ToString();
973 parameters["?regionDataURI"] = regiondata.regionDataURI.ToString();
974 parameters["?serverIP"] = regiondata.serverIP.ToString();
975 parameters["?serverPort"] = regiondata.serverPort.ToString();
976 parameters["?serverURI"] = regiondata.serverURI.ToString();
977 parameters["?locX"] = regiondata.regionLocX.ToString();
978 parameters["?locY"] = regiondata.regionLocY.ToString();
979 parameters["?locZ"] = regiondata.regionLocZ.ToString();
980 parameters["?eastOverrideHandle"] = regiondata.regionEastOverrideHandle.ToString();
981 parameters["?westOverrideHandle"] = regiondata.regionWestOverrideHandle.ToString();
982 parameters["?northOverrideHandle"] = regiondata.regionNorthOverrideHandle.ToString();
983 parameters["?southOverrideHandle"] = regiondata.regionSouthOverrideHandle.ToString();
984 parameters["?regionAssetURI"] = regiondata.regionAssetURI.ToString();
985 parameters["?regionAssetRecvKey"] = regiondata.regionAssetRecvKey.ToString();
986 parameters["?regionAssetSendKey"] = regiondata.regionAssetSendKey.ToString();
987 parameters["?regionUserURI"] = regiondata.regionUserURI.ToString();
988 parameters["?regionUserRecvKey"] = regiondata.regionUserRecvKey.ToString();
989 parameters["?regionUserSendKey"] = regiondata.regionUserSendKey.ToString();
990 parameters["?regionMapTexture"] = regiondata.regionMapTextureID.ToString();
991 parameters["?serverHttpPort"] = regiondata.httpPort.ToString();
992 parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString();
993 parameters["?owner_uuid"] = regiondata.owner_uuid.ToString();
994 parameters["?originUUID"] = regiondata.originUUID.ToString();
995 parameters["?access"] = regiondata.maturity.ToString();
996
997 bool returnval = false;
998
999 try
1000 {
1001 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
1002 {
1003 dbcon.Open();
1004
1005 IDbCommand result = Query(dbcon, sql, parameters);
1006
1007 // int x;
1008 // if ((x = result.ExecuteNonQuery()) > 0)
1009 // {
1010 // returnval = true;
1011 // }
1012 if (result.ExecuteNonQuery() > 0)
1013 {
1014 returnval = true;
1015 }
1016 result.Dispose();
1017 }
1018 }
1019 catch (Exception e)
1020 {
1021 m_log.Error(e.ToString());
1022 return false;
1023 }
1024
1025 return returnval;
1026 }
1027
1028 /// <summary>
1029 /// Delete a region from the database
1030 /// </summary>
1031 /// <param name="uuid">The region to delete</param>
1032 /// <returns>Success?</returns>
1033 //public bool deleteRegion(RegionProfileData regiondata)
1034 public bool deleteRegion(string uuid)
1035 {
1036 bool returnval = false;
1037
1038 string sql = "DELETE FROM regions WHERE uuid = ?uuid;";
1039
1040 Dictionary<string, object> parameters = new Dictionary<string, object>();
1041
1042 try
1043 {
1044 parameters["?uuid"] = uuid;
1045
1046 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
1047 {
1048 dbcon.Open();
1049
1050 IDbCommand result = Query(dbcon, sql, parameters);
1051
1052 // int x;
1053 // if ((x = result.ExecuteNonQuery()) > 0)
1054 // {
1055 // returnval = true;
1056 // }
1057 if (result.ExecuteNonQuery() > 0)
1058 {
1059 returnval = true;
1060 }
1061 result.Dispose();
1062 }
1063 }
1064 catch (Exception e)
1065 {
1066 m_log.Error(e.ToString());
1067 return false;
1068 }
1069
1070 return returnval;
1071 }
1072
1073 /// <summary>
1074 /// Creates a new agent and inserts it into the database
1075 /// </summary>
1076 /// <param name="agentdata">The agent data to be inserted</param>
1077 /// <returns>Success?</returns>
1078 public bool insertAgentRow(UserAgentData agentdata)
1079 {
1080 string sql = String.Empty;
1081 sql += "REPLACE INTO ";
1082 sql += "agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos, currentLookAt) VALUES ";
1083 sql += "(?UUID, ?sessionID, ?secureSessionID, ?agentIP, ?agentPort, ?agentOnline, ?loginTime, ?logoutTime, ?currentRegion, ?currentHandle, ?currentPos, ?currentLookAt);";
1084 Dictionary<string, object> parameters = new Dictionary<string, object>();
1085
1086 parameters["?UUID"] = agentdata.ProfileID.ToString();
1087 parameters["?sessionID"] = agentdata.SessionID.ToString();
1088 parameters["?secureSessionID"] = agentdata.SecureSessionID.ToString();
1089 parameters["?agentIP"] = agentdata.AgentIP.ToString();
1090 parameters["?agentPort"] = agentdata.AgentPort.ToString();
1091 parameters["?agentOnline"] = (agentdata.AgentOnline == true) ? "1" : "0";
1092 parameters["?loginTime"] = agentdata.LoginTime.ToString();
1093 parameters["?logoutTime"] = agentdata.LogoutTime.ToString();
1094 parameters["?currentRegion"] = agentdata.Region.ToString();
1095 parameters["?currentHandle"] = agentdata.Handle.ToString();
1096 parameters["?currentPos"] = "<" + (agentdata.Position.X).ToString().Replace(",", ".") + "," + (agentdata.Position.Y).ToString().Replace(",", ".") + "," + (agentdata.Position.Z).ToString().Replace(",", ".") + ">";
1097 parameters["?currentLookAt"] = "<" + (agentdata.LookAt.X).ToString().Replace(",", ".") + "," + (agentdata.LookAt.Y).ToString().Replace(",", ".") + "," + (agentdata.LookAt.Z).ToString().Replace(",", ".") + ">";
1098
1099 bool returnval = false;
1100
1101 try
1102 {
1103 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
1104 {
1105 dbcon.Open();
1106
1107 IDbCommand result = Query(dbcon, sql, parameters);
1108
1109 // int x;
1110 // if ((x = result.ExecuteNonQuery()) > 0)
1111 // {
1112 // returnval = true;
1113 // }
1114 if (result.ExecuteNonQuery() > 0)
1115 {
1116 returnval = true;
1117 }
1118 result.Dispose();
1119 }
1120 }
1121 catch (Exception e)
1122 {
1123 m_log.Error(e.ToString());
1124 return false;
1125 }
1126
1127 return returnval;
1128 }
1129
1130 /// <summary>
1131 /// Create (or replace if existing) an avatar appearence
1132 /// </summary>
1133 /// <param name="appearance"></param>
1134 /// <returns>Succes?</returns>
1135 public bool insertAppearanceRow(AvatarAppearance appearance)
1136 {
1137 string sql = String.Empty;
1138 sql += "REPLACE INTO ";
1139 sql += "avatarappearance (owner, serial, visual_params, texture, avatar_height, ";
1140 sql += "body_item, body_asset, skin_item, skin_asset, hair_item, hair_asset, eyes_item, eyes_asset, ";
1141 sql += "shirt_item, shirt_asset, pants_item, pants_asset, shoes_item, shoes_asset, socks_item, socks_asset, ";
1142 sql += "jacket_item, jacket_asset, gloves_item, gloves_asset, undershirt_item, undershirt_asset, underpants_item, underpants_asset, ";
1143 sql += "skirt_item, skirt_asset) values (";
1144 sql += "?owner, ?serial, ?visual_params, ?texture, ?avatar_height, ";
1145 sql += "?body_item, ?body_asset, ?skin_item, ?skin_asset, ?hair_item, ?hair_asset, ?eyes_item, ?eyes_asset, ";
1146 sql += "?shirt_item, ?shirt_asset, ?pants_item, ?pants_asset, ?shoes_item, ?shoes_asset, ?socks_item, ?socks_asset, ";
1147 sql += "?jacket_item, ?jacket_asset, ?gloves_item, ?gloves_asset, ?undershirt_item, ?undershirt_asset, ?underpants_item, ?underpants_asset, ";
1148 sql += "?skirt_item, ?skirt_asset)";
1149
1150 bool returnval = false;
1151
1152 // we want to send in byte data, which means we can't just pass down strings
1153 try
1154 {
1155 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
1156 {
1157 dbcon.Open();
1158
1159 using (MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand())
1160 {
1161 cmd.CommandText = sql;
1162 cmd.Parameters.AddWithValue("?owner", appearance.Owner.ToString());
1163 cmd.Parameters.AddWithValue("?serial", appearance.Serial);
1164 cmd.Parameters.AddWithValue("?visual_params", appearance.VisualParams);
1165 cmd.Parameters.AddWithValue("?texture", appearance.Texture.GetBytes());
1166 cmd.Parameters.AddWithValue("?avatar_height", appearance.AvatarHeight);
1167 cmd.Parameters.AddWithValue("?body_item", appearance.BodyItem.ToString());
1168 cmd.Parameters.AddWithValue("?body_asset", appearance.BodyAsset.ToString());
1169 cmd.Parameters.AddWithValue("?skin_item", appearance.SkinItem.ToString());
1170 cmd.Parameters.AddWithValue("?skin_asset", appearance.SkinAsset.ToString());
1171 cmd.Parameters.AddWithValue("?hair_item", appearance.HairItem.ToString());
1172 cmd.Parameters.AddWithValue("?hair_asset", appearance.HairAsset.ToString());
1173 cmd.Parameters.AddWithValue("?eyes_item", appearance.EyesItem.ToString());
1174 cmd.Parameters.AddWithValue("?eyes_asset", appearance.EyesAsset.ToString());
1175 cmd.Parameters.AddWithValue("?shirt_item", appearance.ShirtItem.ToString());
1176 cmd.Parameters.AddWithValue("?shirt_asset", appearance.ShirtAsset.ToString());
1177 cmd.Parameters.AddWithValue("?pants_item", appearance.PantsItem.ToString());
1178 cmd.Parameters.AddWithValue("?pants_asset", appearance.PantsAsset.ToString());
1179 cmd.Parameters.AddWithValue("?shoes_item", appearance.ShoesItem.ToString());
1180 cmd.Parameters.AddWithValue("?shoes_asset", appearance.ShoesAsset.ToString());
1181 cmd.Parameters.AddWithValue("?socks_item", appearance.SocksItem.ToString());
1182 cmd.Parameters.AddWithValue("?socks_asset", appearance.SocksAsset.ToString());
1183 cmd.Parameters.AddWithValue("?jacket_item", appearance.JacketItem.ToString());
1184 cmd.Parameters.AddWithValue("?jacket_asset", appearance.JacketAsset.ToString());
1185 cmd.Parameters.AddWithValue("?gloves_item", appearance.GlovesItem.ToString());
1186 cmd.Parameters.AddWithValue("?gloves_asset", appearance.GlovesAsset.ToString());
1187 cmd.Parameters.AddWithValue("?undershirt_item", appearance.UnderShirtItem.ToString());
1188 cmd.Parameters.AddWithValue("?undershirt_asset", appearance.UnderShirtAsset.ToString());
1189 cmd.Parameters.AddWithValue("?underpants_item", appearance.UnderPantsItem.ToString());
1190 cmd.Parameters.AddWithValue("?underpants_asset", appearance.UnderPantsAsset.ToString());
1191 cmd.Parameters.AddWithValue("?skirt_item", appearance.SkirtItem.ToString());
1192 cmd.Parameters.AddWithValue("?skirt_asset", appearance.SkirtAsset.ToString());
1193
1194 if (cmd.ExecuteNonQuery() > 0)
1195 returnval = true;
1196 }
1197 }
1198 }
1199 catch (Exception e)
1200 {
1201 m_log.Error(e.ToString());
1202 return false;
1203 }
1204
1205 return returnval;
1206
1207 }
1208
1209 public void writeAttachments(UUID agentID, Hashtable data)
1210 {
1211 string sql = "delete from avatarattachments where UUID = ?uuid";
1212
1213 using (MySqlConnection dbcon = new MySqlConnection(connectionString))
1214 {
1215 dbcon.Open();
1216
1217 MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand();
1218 cmd.CommandText = sql;
1219 cmd.Parameters.AddWithValue("?uuid", agentID.ToString());
1220
1221 cmd.ExecuteNonQuery();
1222
1223 if (data == null)
1224 return;
1225
1226 sql = "insert into avatarattachments (UUID, attachpoint, item, asset) values (?uuid, ?attachpoint, ?item, ?asset)";
1227
1228 cmd = (MySqlCommand)dbcon.CreateCommand();
1229 cmd.CommandText = sql;
1230
1231 foreach (DictionaryEntry e in data)
1232 {
1233 int attachpoint = Convert.ToInt32(e.Key);
1234
1235 Hashtable item = (Hashtable)e.Value;
1236
1237 cmd.Parameters.Clear();
1238 cmd.Parameters.AddWithValue("?uuid", agentID.ToString());
1239 cmd.Parameters.AddWithValue("?attachpoint", attachpoint);
1240 cmd.Parameters.AddWithValue("?item", item["item"]);
1241 cmd.Parameters.AddWithValue("?asset", item["asset"]);
1242
1243 cmd.ExecuteNonQuery();
1244 }
1245 }
1246 }
1247 }
1248}
diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs
new file mode 100644
index 0000000..143dbe3
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs
@@ -0,0 +1,155 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using MySql.Data.MySqlClient;
37
38namespace OpenSim.Data.MySQL
39{
40 /// <summary>
41 /// A MySQL Interface for the Grid Server
42 /// </summary>
43 public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>,
44 IPresenceData
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public MySQLPresenceData(string connectionString, string realm) :
49 base(connectionString, realm, "Presence")
50 {
51 }
52
53 public PresenceData Get(UUID sessionID)
54 {
55 PresenceData[] ret = Get("SessionID",
56 sessionID.ToString());
57
58 if (ret.Length == 0)
59 return null;
60
61 return ret[0];
62 }
63
64 public void LogoutRegionAgents(UUID regionID)
65 {
66 MySqlCommand cmd = new MySqlCommand();
67
68 cmd.CommandText = String.Format("update {0} set Online='false' where `RegionID`=?RegionID", m_Realm);
69
70 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
71
72 ExecuteNonQuery(cmd);
73 }
74
75 public bool ReportAgent(UUID sessionID, UUID regionID, string position,
76 string lookAt)
77 {
78 PresenceData[] pd = Get("SessionID", sessionID.ToString());
79 if (pd.Length == 0)
80 return false;
81
82 MySqlCommand cmd = new MySqlCommand();
83
84 cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, Position=?Position, LookAt=?LookAt, Online='true' where `SessionID`=?SessionID", m_Realm);
85
86 cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
87 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
88 cmd.Parameters.AddWithValue("?Position", position.ToString());
89 cmd.Parameters.AddWithValue("?LookAt", lookAt.ToString());
90
91 if (ExecuteNonQuery(cmd) == 0)
92 return false;
93
94 return true;
95 }
96
97 public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
98 {
99 PresenceData[] pd = Get("UserID", userID);
100 if (pd.Length == 0)
101 return false;
102
103 MySqlCommand cmd = new MySqlCommand();
104
105 cmd.CommandText = String.Format("update {0} set HomeRegionID=?HomeRegionID, HomePosition=?HomePosition, HomeLookAt=?HomeLookAt where UserID=?UserID", m_Realm);
106
107 cmd.Parameters.AddWithValue("?UserID", userID);
108 cmd.Parameters.AddWithValue("?HomeRegionID", regionID.ToString());
109 cmd.Parameters.AddWithValue("?HomePosition", position);
110 cmd.Parameters.AddWithValue("?HomeLookAt", lookAt);
111
112 if (ExecuteNonQuery(cmd) == 0)
113 return false;
114
115 return true;
116 }
117
118 public void Prune(string userID)
119 {
120 MySqlCommand cmd = new MySqlCommand();
121
122 cmd.CommandText = String.Format("select * from {0} where UserID=?UserID", m_Realm);
123
124 cmd.Parameters.AddWithValue("?UserID", userID);
125
126 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
127 {
128 dbcon.Open();
129
130 cmd.Connection = dbcon;
131
132 using (IDataReader reader = cmd.ExecuteReader())
133 {
134 List<UUID> deleteSessions = new List<UUID>();
135 int online = 0;
136
137 while (reader.Read())
138 {
139 if (bool.Parse(reader["Online"].ToString()))
140 online++;
141 else
142 deleteSessions.Add(new UUID(reader["SessionID"].ToString()));
143 }
144
145 // Leave one session behind so that we can pick up details such as home location
146 if (online == 0 && deleteSessions.Count > 0)
147 deleteSessions.RemoveAt(0);
148
149 foreach (UUID s in deleteSessions)
150 Delete("SessionID", s.ToString());
151 }
152 }
153 }
154 }
155}
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs
index a1a08b1..aa9a104 100644
--- a/OpenSim/Data/MySQL/MySQLRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLRegionData.cs
@@ -283,5 +283,31 @@ namespace OpenSim.Data.MySQL
283 283
284 return false; 284 return false;
285 } 285 }
286 public List<RegionData> GetDefaultRegions(UUID scopeID)
287 {
288 string command = "select * from `"+m_Realm+"` where (flags & 1) <> 0";
289 if (scopeID != UUID.Zero)
290 command += " and ScopeID = ?scopeID";
291
292 MySqlCommand cmd = new MySqlCommand(command);
293
294 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
295
296 return RunCommand(cmd);
297 }
298
299 public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
300 {
301 string command = "select * from `"+m_Realm+"` where (flags & 2) <> 0";
302 if (scopeID != UUID.Zero)
303 command += " and ScopeID = ?scopeID";
304
305 MySqlCommand cmd = new MySqlCommand(command);
306
307 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
308
309 // TODO: distance-sort results
310 return RunCommand(cmd);
311 }
286 } 312 }
287} 313}
diff --git a/OpenSim/Data/MySQL/MySQLSuperManager.cs b/OpenSim/Data/MySQL/MySQLSuperManager.cs
deleted file mode 100644
index c579432..0000000
--- a/OpenSim/Data/MySQL/MySQLSuperManager.cs
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Threading;
29
30namespace OpenSim.Data.MySQL
31{
32 public class MySQLSuperManager
33 {
34 public bool Locked;
35 private readonly Mutex m_lock = new Mutex(false);
36 public MySQLManager Manager;
37 public string Running;
38
39 public void GetLock()
40 {
41 Locked = true;
42 m_lock.WaitOne();
43 }
44
45 public void Release()
46 {
47 m_lock.ReleaseMutex();
48 Locked = false;
49 }
50
51 }
52}
diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs
index 3cb0010..aa69d68 100644
--- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs
+++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs
@@ -35,150 +35,50 @@ using MySql.Data.MySqlClient;
35 35
36namespace OpenSim.Data.MySQL 36namespace OpenSim.Data.MySQL
37{ 37{
38 public class MySqlUserAccountData : MySqlFramework, IUserAccountData 38 public class MySqlUserAccountData : MySQLGenericTableHandler<UserAccountData>, IUserAccountData
39 { 39 {
40 private string m_Realm;
41 private List<string> m_ColumnNames;
42 // private string m_connectionString;
43
44 public MySqlUserAccountData(string connectionString, string realm) 40 public MySqlUserAccountData(string connectionString, string realm)
45 : base(connectionString) 41 : base(connectionString, realm, "UserAccount")
46 {
47 m_Realm = realm;
48 m_connectionString = connectionString;
49
50 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
51 {
52 dbcon.Open();
53 Migration m = new Migration(dbcon, GetType().Assembly, "UserStore");
54 m.Update();
55 }
56 }
57
58 public List<UserAccountData> Query(UUID principalID, UUID scopeID, string query)
59 { 42 {
60 return null;
61 } 43 }
62 44
63 public UserAccountData Get(UUID principalID, UUID scopeID) 45 public UserAccountData[] GetUsers(UUID scopeID, string query)
64 { 46 {
65 UserAccountData ret = new UserAccountData(); 47 string[] words = query.Split(new char[] {' '});
66 ret.Data = new Dictionary<string, object>();
67
68 string command = "select * from `"+m_Realm+"` where UUID = ?principalID";
69 if (scopeID != UUID.Zero)
70 command += " and ScopeID = ?scopeID";
71 48
72 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 49 for (int i = 0 ; i < words.Length ; i++)
73 { 50 {
74 dbcon.Open(); 51 if (words[i].Length < 3)
75 MySqlCommand cmd = new MySqlCommand(command, dbcon);
76
77 cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
78 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
79
80 IDataReader result = cmd.ExecuteReader();
81
82 if (result.Read())
83 { 52 {
84 ret.PrincipalID = principalID; 53 if (i != words.Length - 1)
85 UUID scope; 54 Array.Copy(words, i + 1, words, i, words.Length - i - 1);
86 UUID.TryParse(result["ScopeID"].ToString(), out scope); 55 Array.Resize(ref words, words.Length - 1);
87 ret.ScopeID = scope;
88
89 if (m_ColumnNames == null)
90 {
91 m_ColumnNames = new List<string>();
92
93 DataTable schemaTable = result.GetSchemaTable();
94 foreach (DataRow row in schemaTable.Rows)
95 m_ColumnNames.Add(row["ColumnName"].ToString());
96 }
97
98 foreach (string s in m_ColumnNames)
99 {
100 if (s == "UUID")
101 continue;
102 if (s == "ScopeID")
103 continue;
104
105 ret.Data[s] = result[s].ToString();
106 }
107
108 return ret;
109 }
110 else
111 {
112 return null;
113 } 56 }
114 } 57 }
115 }
116 58
117 public bool Store(UserAccountData data) 59 if (words.Length == 0)
118 { 60 return new UserAccountData[0];
119 if (data.Data.ContainsKey("UUID"))
120 data.Data.Remove("UUID");
121 if (data.Data.ContainsKey("ScopeID"))
122 data.Data.Remove("ScopeID");
123
124 string[] fields = new List<string>(data.Data.Keys).ToArray();
125
126 using (MySqlCommand cmd = new MySqlCommand())
127 {
128 string update = "update `" + m_Realm + "` set ";
129 bool first = true;
130 foreach (string field in fields)
131 {
132 if (!first)
133 update += ", ";
134 update += "`" + field + "` = ?" + field;
135 61
136 first = false; 62 if (words.Length > 2)
63 return new UserAccountData[0];
137 64
138 cmd.Parameters.AddWithValue("?" + field, data.Data[field]); 65 MySqlCommand cmd = new MySqlCommand();
139 }
140
141 update += " where UUID = ?principalID";
142
143 if (data.ScopeID != UUID.Zero)
144 update += " and ScopeID = ?scopeID";
145 66
146 cmd.CommandText = update; 67 if (words.Length == 1)
147 cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); 68 {
148 cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); 69 cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
149 70 cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
150 if (ExecuteNonQuery(cmd) < 1) 71 cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
151 {
152 string insert = "insert into `" + m_Realm + "` (`UUID`, `ScopeID`, `" +
153 String.Join("`, `", fields) +
154 "`) values (?principalID, ?scopeID, ?" + String.Join(", ?", fields) + ")";
155
156 cmd.CommandText = insert;
157
158 if (ExecuteNonQuery(cmd) < 1)
159 {
160 cmd.Dispose();
161 return false;
162 }
163 }
164 } 72 }
165 73 else
166 return true;
167 }
168
169 public bool SetDataItem(UUID principalID, string item, string value)
170 {
171 using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" +
172 item + "` = ?" + item + " where UUID = ?UUID"))
173 { 74 {
174 cmd.Parameters.AddWithValue("?" + item, value); 75 cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
175 cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); 76 cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
176 77 cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
177 if (ExecuteNonQuery(cmd) > 0) 78 cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
178 return true;
179 } 79 }
180 80
181 return false; 81 return DoQuery(cmd);
182 } 82 }
183 } 83 }
184} 84}
diff --git a/OpenSim/Data/MySQL/MySQLUserData.cs b/OpenSim/Data/MySQL/MySQLUserData.cs
deleted file mode 100644
index 0a9d2e3..0000000
--- a/OpenSim/Data/MySQL/MySQLUserData.cs
+++ /dev/null
@@ -1,766 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using System.Threading;
35using log4net;
36using MySql.Data.MySqlClient;
37using OpenMetaverse;
38using OpenSim.Framework;
39
40namespace OpenSim.Data.MySQL
41{
42 /// <summary>
43 /// A database interface class to a user profile storage system
44 /// </summary>
45 public class MySQLUserData : UserDataBase
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private MySQLManager m_database;
50 private string m_connectionString;
51 private object m_dbLock = new object();
52
53 public int m_maxConnections = 10;
54 public int m_lastConnect;
55
56 private string m_agentsTableName = "agents";
57 private string m_usersTableName = "users";
58 private string m_userFriendsTableName = "userfriends";
59 private string m_appearanceTableName = "avatarappearance";
60 private string m_attachmentsTableName = "avatarattachments";
61
62 public override void Initialise()
63 {
64 m_log.Info("[MySQLUserData]: " + Name + " cannot be default-initialized!");
65 throw new PluginNotInitialisedException(Name);
66 }
67
68 /// <summary>
69 /// Initialise User Interface
70 /// Loads and initialises the MySQL storage plugin
71 /// Warns and uses the obsolete mysql_connection.ini if connect string is empty.
72 /// Checks for migration
73 /// </summary>
74 /// <param name="connect">connect string.</param>
75 public override void Initialise(string connect)
76 {
77 m_connectionString = connect;
78 m_database = new MySQLManager(connect);
79
80 // This actually does the roll forward assembly stuff
81 Assembly assem = GetType().Assembly;
82
83 using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(m_connectionString))
84 {
85 dbcon.Open();
86 Migration m = new Migration(dbcon, assem, "UserStore");
87 m.Update();
88 }
89 }
90
91 public override void Dispose()
92 {
93 }
94
95 // see IUserDataPlugin
96 public override UserProfileData GetUserByName(string user, string last)
97 {
98 try
99 {
100 Dictionary<string, object> param = new Dictionary<string, object>();
101 param["?first"] = user;
102 param["?second"] = last;
103
104 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
105 {
106 dbcon.Open();
107
108 using (IDbCommand result = m_database.Query(dbcon,
109 "SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param))
110 {
111 using (IDataReader reader = result.ExecuteReader())
112 {
113 UserProfileData row = m_database.readUserRow(reader);
114 return row;
115 }
116 }
117 }
118 }
119 catch (Exception e)
120 {
121 m_log.Error(e.Message, e);
122 return null;
123 }
124 }
125
126 #region User Friends List Data
127
128 public override void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
129 {
130 int dtvalue = Util.UnixTimeSinceEpoch();
131
132 Dictionary<string, object> param = new Dictionary<string, object>();
133 param["?ownerID"] = friendlistowner.ToString();
134 param["?friendID"] = friend.ToString();
135 param["?friendPerms"] = perms.ToString();
136 param["?datetimestamp"] = dtvalue.ToString();
137
138 try
139 {
140 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
141 {
142 dbcon.Open();
143
144 using (IDbCommand adder = m_database.Query(dbcon,
145 "INSERT INTO `" + m_userFriendsTableName + "` " +
146 "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
147 "VALUES " +
148 "(?ownerID,?friendID,?friendPerms,?datetimestamp)",
149 param))
150 {
151 adder.ExecuteNonQuery();
152 }
153
154 using (IDbCommand adder = m_database.Query(dbcon,
155 "INSERT INTO `" + m_userFriendsTableName + "` " +
156 "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
157 "VALUES " +
158 "(?friendID,?ownerID,?friendPerms,?datetimestamp)",
159 param))
160 {
161 adder.ExecuteNonQuery();
162 }
163 }
164 }
165 catch (Exception e)
166 {
167 m_log.Error(e.Message, e);
168 return;
169 }
170 }
171
172 public override void RemoveUserFriend(UUID friendlistowner, UUID friend)
173 {
174 Dictionary<string, object> param = new Dictionary<string, object>();
175 param["?ownerID"] = friendlistowner.ToString();
176 param["?friendID"] = friend.ToString();
177
178 try
179 {
180 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
181 {
182 dbcon.Open();
183
184 using (IDbCommand updater = m_database.Query(dbcon,
185 "delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID",
186 param))
187 {
188 updater.ExecuteNonQuery();
189 }
190
191 using (IDbCommand updater = m_database.Query(dbcon,
192 "delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID",
193 param))
194 {
195 updater.ExecuteNonQuery();
196 }
197 }
198 }
199 catch (Exception e)
200 {
201 m_log.Error(e.Message, e);
202 return;
203 }
204 }
205
206 public override void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
207 {
208 Dictionary<string, object> param = new Dictionary<string, object>();
209 param["?ownerID"] = friendlistowner.ToString();
210 param["?friendID"] = friend.ToString();
211 param["?friendPerms"] = perms.ToString();
212
213 try
214 {
215 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
216 {
217 dbcon.Open();
218
219 using (IDbCommand updater = m_database.Query(dbcon,
220 "update " + m_userFriendsTableName +
221 " SET friendPerms = ?friendPerms " +
222 "where ownerID = ?ownerID and friendID = ?friendID",
223 param))
224 {
225 updater.ExecuteNonQuery();
226 }
227 }
228 }
229 catch (Exception e)
230 {
231 m_log.Error(e.Message, e);
232 return;
233 }
234 }
235
236 public override List<FriendListItem> GetUserFriendList(UUID friendlistowner)
237 {
238 List<FriendListItem> Lfli = new List<FriendListItem>();
239
240 Dictionary<string, object> param = new Dictionary<string, object>();
241 param["?ownerID"] = friendlistowner.ToString();
242
243 try
244 {
245 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
246 {
247 dbcon.Open();
248
249 //Left Join userfriends to itself
250 using (IDbCommand result = m_database.Query(dbcon,
251 "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " +
252 m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" +
253 " where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID",
254 param))
255 {
256 using (IDataReader reader = result.ExecuteReader())
257 {
258 while (reader.Read())
259 {
260 FriendListItem fli = new FriendListItem();
261 fli.FriendListOwner = new UUID((string)reader["ownerID"]);
262 fli.Friend = new UUID((string)reader["friendID"]);
263 fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]);
264
265 // This is not a real column in the database table, it's a joined column from the opposite record
266 fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]);
267
268 Lfli.Add(fli);
269 }
270 }
271 }
272 }
273 }
274 catch (Exception e)
275 {
276 m_log.Error(e.Message, e);
277 return Lfli;
278 }
279
280 return Lfli;
281 }
282
283 override public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids)
284 {
285 Dictionary<UUID, FriendRegionInfo> infos = new Dictionary<UUID,FriendRegionInfo>();
286
287 try
288 {
289 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
290 {
291 dbcon.Open();
292
293 foreach (UUID uuid in uuids)
294 {
295 Dictionary<string, object> param = new Dictionary<string, object>();
296 param["?uuid"] = uuid.ToString();
297
298 using (IDbCommand result = m_database.Query(dbcon, "select agentOnline,currentHandle from " + m_agentsTableName +
299 " where UUID = ?uuid", param))
300 {
301 using (IDataReader reader = result.ExecuteReader())
302 {
303 while (reader.Read())
304 {
305 FriendRegionInfo fri = new FriendRegionInfo();
306 fri.isOnline = (sbyte)reader["agentOnline"] != 0;
307 fri.regionHandle = (ulong)reader["currentHandle"];
308
309 infos[uuid] = fri;
310 }
311 }
312 }
313 }
314 }
315 }
316 catch (Exception e)
317 {
318 m_log.Warn("[MYSQL]: Got exception on trying to find friends regions:", e);
319 m_log.Error(e.Message, e);
320 }
321
322 return infos;
323 }
324
325 #endregion
326
327 public override List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query)
328 {
329 List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
330
331 Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
332
333 string[] querysplit;
334 querysplit = query.Split(' ');
335 if (querysplit.Length > 1 && querysplit[1].Trim() != String.Empty)
336 {
337 Dictionary<string, object> param = new Dictionary<string, object>();
338 param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
339 param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], String.Empty) + "%";
340
341 try
342 {
343 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
344 {
345 dbcon.Open();
346
347 using (IDbCommand result = m_database.Query(dbcon,
348 "SELECT UUID,username,lastname FROM " + m_usersTableName +
349 " WHERE username like ?first AND lastname like ?second LIMIT 100",
350 param))
351 {
352 using (IDataReader reader = result.ExecuteReader())
353 {
354 while (reader.Read())
355 {
356 AvatarPickerAvatar user = new AvatarPickerAvatar();
357 user.AvatarID = new UUID((string)reader["UUID"]);
358 user.firstName = (string)reader["username"];
359 user.lastName = (string)reader["lastname"];
360 returnlist.Add(user);
361 }
362 }
363 }
364 }
365 }
366 catch (Exception e)
367 {
368 m_log.Error(e.Message, e);
369 return returnlist;
370 }
371 }
372 else
373 {
374 try
375 {
376 Dictionary<string, object> param = new Dictionary<string, object>();
377 param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
378
379 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
380 {
381 dbcon.Open();
382
383 using (IDbCommand result = m_database.Query(dbcon,
384 "SELECT UUID,username,lastname FROM " + m_usersTableName +
385 " WHERE username like ?first OR lastname like ?first LIMIT 100",
386 param))
387 {
388 using (IDataReader reader = result.ExecuteReader())
389 {
390 while (reader.Read())
391 {
392 AvatarPickerAvatar user = new AvatarPickerAvatar();
393 user.AvatarID = new UUID((string)reader["UUID"]);
394 user.firstName = (string)reader["username"];
395 user.lastName = (string)reader["lastname"];
396 returnlist.Add(user);
397 }
398 }
399 }
400 }
401 }
402 catch (Exception e)
403 {
404 m_log.Error(e.Message, e);
405 return returnlist;
406 }
407 }
408 return returnlist;
409 }
410
411 /// <summary>
412 /// See IUserDataPlugin
413 /// </summary>
414 /// <param name="uuid">User UUID</param>
415 /// <returns>User profile data</returns>
416 public override UserProfileData GetUserByUUID(UUID uuid)
417 {
418 try
419 {
420 Dictionary<string, object> param = new Dictionary<string, object>();
421 param["?uuid"] = uuid.ToString();
422
423 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
424 {
425 dbcon.Open();
426
427 using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param))
428 {
429 using (IDataReader reader = result.ExecuteReader())
430 {
431 UserProfileData row = m_database.readUserRow(reader);
432 return row;
433 }
434 }
435 }
436 }
437 catch (Exception e)
438 {
439 m_log.Error(e.Message, e);
440 return null;
441 }
442 }
443
444 /// <summary>
445 /// Returns a user session searching by name
446 /// </summary>
447 /// <param name="name">The account name : "Username Lastname"</param>
448 /// <returns>The users session</returns>
449 public override UserAgentData GetAgentByName(string name)
450 {
451 return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
452 }
453
454 /// <summary>
455 /// Returns a user session by account name
456 /// </summary>
457 /// <param name="user">First part of the users account name</param>
458 /// <param name="last">Second part of the users account name</param>
459 /// <returns>The users session</returns>
460 public override UserAgentData GetAgentByName(string user, string last)
461 {
462 UserProfileData profile = GetUserByName(user, last);
463 return GetAgentByUUID(profile.ID);
464 }
465
466 /// <summary>
467 /// </summary>
468 /// <param name="AgentID"></param>
469 /// <param name="WebLoginKey"></param>
470 /// <remarks>is it still used ?</remarks>
471 public override void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey)
472 {
473 Dictionary<string, string> param = new Dictionary<string, string>();
474 param["?UUID"] = AgentID.ToString();
475 param["?webLoginKey"] = WebLoginKey.ToString();
476
477 try
478 {
479 m_database.ExecuteParameterizedSql(
480 "update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " +
481 "where UUID = ?UUID",
482 param);
483 }
484 catch (Exception e)
485 {
486 m_log.Error(e.Message, e);
487 return;
488 }
489 }
490
491 /// <summary>
492 /// Returns an agent session by account UUID
493 /// </summary>
494 /// <param name="uuid">The accounts UUID</param>
495 /// <returns>The users session</returns>
496 public override UserAgentData GetAgentByUUID(UUID uuid)
497 {
498 try
499 {
500 Dictionary<string, object> param = new Dictionary<string, object>();
501 param["?uuid"] = uuid.ToString();
502
503 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
504 {
505 dbcon.Open();
506
507 using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param))
508 {
509 using (IDataReader reader = result.ExecuteReader())
510 {
511 UserAgentData row = m_database.readAgentRow(reader);
512 return row;
513 }
514 }
515 }
516 }
517 catch (Exception e)
518 {
519 m_log.Error(e.Message, e);
520 return null;
521 }
522 }
523
524 /// <summary>
525 /// Creates a new users profile
526 /// </summary>
527 /// <param name="user">The user profile to create</param>
528 public override void AddNewUserProfile(UserProfileData user)
529 {
530 UUID zero = UUID.Zero;
531 if (user.ID == zero)
532 {
533 return;
534 }
535
536 try
537 {
538 m_database.insertUserRow(
539 user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
540 user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y,
541 user.HomeLocation.Z,
542 user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created,
543 user.LastLogin, user.UserInventoryURI, user.UserAssetURI,
544 user.CanDoMask, user.WantDoMask,
545 user.AboutText, user.FirstLifeAboutText, user.Image,
546 user.FirstLifeImage, user.WebLoginKey, user.UserFlags, user.GodLevel, user.CustomType, user.Partner);
547 }
548 catch (Exception e)
549 {
550 m_log.Error(e.Message, e);
551 }
552 }
553
554 /// <summary>
555 /// Creates a new agent
556 /// </summary>
557 /// <param name="agent">The agent to create</param>
558 public override void AddNewUserAgent(UserAgentData agent)
559 {
560 UUID zero = UUID.Zero;
561 if (agent.ProfileID == zero || agent.SessionID == zero)
562 return;
563
564 try
565 {
566 m_database.insertAgentRow(agent);
567 }
568 catch (Exception e)
569 {
570 m_log.Error(e.Message, e);
571 }
572 }
573
574 /// <summary>
575 /// Updates a user profile stored in the DB
576 /// </summary>
577 /// <param name="user">The profile data to use to update the DB</param>
578 public override bool UpdateUserProfile(UserProfileData user)
579 {
580 try
581 {
582 m_database.updateUserRow(
583 user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
584 user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y,
585 user.HomeLocation.Z, user.HomeLookAt.X,
586 user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin,
587 user.UserInventoryURI,
588 user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText,
589 user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey,
590 user.UserFlags, user.GodLevel, user.CustomType, user.Partner);
591
592 return true;
593 }
594 catch
595 {
596 return false;
597 }
598 }
599
600 /// <summary>
601 /// Performs a money transfer request between two accounts
602 /// </summary>
603 /// <param name="from">The senders account ID</param>
604 /// <param name="to">The receivers account ID</param>
605 /// <param name="amount">The amount to transfer</param>
606 /// <returns>Success?</returns>
607 public override bool MoneyTransferRequest(UUID from, UUID to, uint amount)
608 {
609 return false;
610 }
611
612 /// <summary>
613 /// Performs an inventory transfer request between two accounts
614 /// </summary>
615 /// <remarks>TODO: Move to inventory server</remarks>
616 /// <param name="from">The senders account ID</param>
617 /// <param name="to">The receivers account ID</param>
618 /// <param name="item">The item to transfer</param>
619 /// <returns>Success?</returns>
620 public override bool InventoryTransferRequest(UUID from, UUID to, UUID item)
621 {
622 return false;
623 }
624
625 public override AvatarAppearance GetUserAppearance(UUID user)
626 {
627 try
628 {
629 Dictionary<string, object> param = new Dictionary<string, object>();
630 param["?owner"] = user.ToString();
631
632 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
633 {
634 dbcon.Open();
635
636 using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param))
637 {
638 using (IDataReader reader = result.ExecuteReader())
639 {
640 AvatarAppearance appearance = m_database.readAppearanceRow(reader);
641
642 if (appearance == null)
643 {
644 m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString());
645 return null;
646 }
647 else
648 {
649 appearance.SetAttachments(GetUserAttachments(user));
650 return appearance;
651 }
652 }
653 }
654 }
655 }
656 catch (Exception e)
657 {
658 m_log.Error(e.Message, e);
659 return null;
660 }
661 }
662
663 /// <summary>
664 /// Updates an avatar appearence
665 /// </summary>
666 /// <param name="user">The user UUID</param>
667 /// <param name="appearance">The avatar appearance</param>
668 // override
669 public override void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
670 {
671 try
672 {
673 appearance.Owner = user;
674 m_database.insertAppearanceRow(appearance);
675
676 UpdateUserAttachments(user, appearance.GetAttachments());
677 }
678 catch (Exception e)
679 {
680 m_log.Error(e.Message, e);
681 }
682 }
683
684 /// <summary>
685 /// Database provider name
686 /// </summary>
687 /// <returns>Provider name</returns>
688 public override string Name
689 {
690 get { return "MySQL Userdata Interface"; }
691 }
692
693 /// <summary>
694 /// Database provider version
695 /// </summary>
696 /// <returns>provider version</returns>
697 public override string Version
698 {
699 get { return "0.1"; }
700 }
701
702 public Hashtable GetUserAttachments(UUID agentID)
703 {
704 Dictionary<string, object> param = new Dictionary<string, object>();
705 param["?uuid"] = agentID.ToString();
706
707 try
708 {
709 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
710 {
711 dbcon.Open();
712
713 using (IDbCommand result = m_database.Query(dbcon,
714 "SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param))
715 {
716 using (IDataReader reader = result.ExecuteReader())
717 {
718 Hashtable ret = m_database.readAttachments(reader);
719 return ret;
720 }
721 }
722 }
723 }
724 catch (Exception e)
725 {
726 m_log.Error(e.Message, e);
727 return null;
728 }
729 }
730
731 public void UpdateUserAttachments(UUID agentID, Hashtable data)
732 {
733 m_database.writeAttachments(agentID, data);
734 }
735
736 public override void ResetAttachments(UUID userID)
737 {
738 Dictionary<string, string> param = new Dictionary<string, string>();
739 param["?uuid"] = userID.ToString();
740
741 m_database.ExecuteParameterizedSql(
742 "UPDATE " + m_attachmentsTableName +
743 " SET asset = '00000000-0000-0000-0000-000000000000' WHERE UUID = ?uuid",
744 param);
745 }
746
747 public override void LogoutUsers(UUID regionID)
748 {
749 Dictionary<string, string> param = new Dictionary<string, string>();
750 param["?regionID"] = regionID.ToString();
751
752 try
753 {
754 m_database.ExecuteParameterizedSql(
755 "update " + m_agentsTableName + " SET agentOnline = 0 " +
756 "where currentRegion = ?regionID",
757 param);
758 }
759 catch (Exception e)
760 {
761 m_log.Error(e.Message, e);
762 return;
763 }
764 }
765 }
766}
diff --git a/OpenSim/Data/MySQL/Resources/001_Avatar.sql b/OpenSim/Data/MySQL/Resources/001_Avatar.sql
new file mode 100644
index 0000000..27a3072
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/001_Avatar.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3CREATE TABLE Avatars (PrincipalID CHAR(36) NOT NULL, Name VARCHAR(32) NOT NULL, Value VARCHAR(255) NOT NULL DEFAULT '', PRIMARY KEY(PrincipalID, Name), KEY(PrincipalID));
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/001_Friends.sql b/OpenSim/Data/MySQL/Resources/001_Friends.sql
new file mode 100644
index 0000000..e158a2c
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/001_Friends.sql
@@ -0,0 +1,9 @@
1BEGIN;
2
3CREATE TABLE `Friends` (
4 `PrincipalID` CHAR(36) NOT NULL,
5 `FriendID` VARCHAR(255) NOT NULL,
6 `Flags` CHAR(16) NOT NULL DEFAULT '0'
7) ENGINE=InnoDB;
8
9COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/001_FriendsStore.sql b/OpenSim/Data/MySQL/Resources/001_FriendsStore.sql
new file mode 100644
index 0000000..da2c59c
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/001_FriendsStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3CREATE TABLE `Friends` (`PrincipalID` CHAR(36) NOT NULL, `Friend` VARCHAR(255) NOT NULL, `Flags` VARCHAR(16) NOT NULL DEFAULT 0, `Offered` VARCHAR(32) NOT NULL DEFAULT 0, PRIMARY KEY(`PrincipalID`, `Friend`), KEY(`PrincipalID`));
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/001_Presence.sql b/OpenSim/Data/MySQL/Resources/001_Presence.sql
new file mode 100644
index 0000000..b8abaf7
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/001_Presence.sql
@@ -0,0 +1,15 @@
1BEGIN;
2
3CREATE TABLE `Presence` (
4 `UserID` VARCHAR(255) NOT NULL,
5 `RegionID` CHAR(36) NOT NULL,
6 `SessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
7 `SecureSessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 `Online` CHAR(5) NOT NULL DEFAULT 'false',
9 `Login` CHAR(16) NOT NULL DEFAULT '0',
10 `Logout` CHAR(16) NOT NULL DEFAULT '0',
11 `Position` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
12 `LookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>'
13) ENGINE=InnoDB;
14
15COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/001_UserAccount.sql b/OpenSim/Data/MySQL/Resources/001_UserAccount.sql
new file mode 100644
index 0000000..07da571
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/001_UserAccount.sql
@@ -0,0 +1,13 @@
1BEGIN;
2
3CREATE TABLE `UserAccounts` (
4 `PrincipalID` CHAR(36) NOT NULL,
5 `ScopeID` CHAR(36) NOT NULL,
6 `FirstName` VARCHAR(64) NOT NULL,
7 `LastName` VARCHAR(64) NOT NULL,
8 `Email` VARCHAR(64),
9 `ServiceURLs` TEXT,
10 `Created` INT(11)
11) ENGINE=InnoDB DEFAULT CHARSET=utf8;
12
13COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/002_AuthStore.sql b/OpenSim/Data/MySQL/Resources/002_AuthStore.sql
new file mode 100644
index 0000000..dc7dfe0
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/002_AuthStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users;
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/002_Friends.sql b/OpenSim/Data/MySQL/Resources/002_Friends.sql
new file mode 100644
index 0000000..5ff6438
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/002_Friends.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3INSERT INTO Friends (PrincipalID, FriendID, Flags) SELECT ownerID, friendID, friendPerms FROM userfriends;
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/002_FriendsStore.sql b/OpenSim/Data/MySQL/Resources/002_FriendsStore.sql
new file mode 100644
index 0000000..a363867
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/002_FriendsStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`;
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/002_Presence.sql b/OpenSim/Data/MySQL/Resources/002_Presence.sql
new file mode 100644
index 0000000..e65f105
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/002_Presence.sql
@@ -0,0 +1,7 @@
1BEGIN;
2
3ALTER TABLE Presence ADD COLUMN `HomeRegionID` CHAR(36) NOT NULL;
4ALTER TABLE Presence ADD COLUMN `HomePosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>';
5ALTER TABLE Presence ADD COLUMN `HomeLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>';
6
7COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/002_UserAccount.sql b/OpenSim/Data/MySQL/Resources/002_UserAccount.sql
new file mode 100644
index 0000000..ad2ddda
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/002_UserAccount.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, lastname AS LastName, email as Email, CONCAT('AssetServerURI=', userAssetURI, ' InventoryServerURI=', userInventoryURI, ' GatewayURI= HomeURI=') AS ServiceURLs, created as Created FROM users;
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/003_AuthStore.sql b/OpenSim/Data/MySQL/Resources/003_AuthStore.sql
new file mode 100644
index 0000000..af9ffe6
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/003_AuthStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE `auth` ADD COLUMN `accountType` VARCHAR(32) NOT NULL DEFAULT 'UserAccount';
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/003_Presence.sql b/OpenSim/Data/MySQL/Resources/003_Presence.sql
new file mode 100644
index 0000000..0efefa8
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/003_Presence.sql
@@ -0,0 +1,6 @@
1BEGIN;
2
3CREATE UNIQUE INDEX SessionID ON Presence(SessionID);
4CREATE INDEX UserID ON Presence(UserID);
5
6COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/003_UserAccount.sql b/OpenSim/Data/MySQL/Resources/003_UserAccount.sql
new file mode 100644
index 0000000..e42d93b
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/003_UserAccount.sql
@@ -0,0 +1,9 @@
1BEGIN;
2
3CREATE UNIQUE INDEX PrincipalID ON UserAccounts(PrincipalID);
4CREATE INDEX Email ON UserAccounts(Email);
5CREATE INDEX FirstName ON UserAccounts(FirstName);
6CREATE INDEX LastName ON UserAccounts(LastName);
7CREATE INDEX Name ON UserAccounts(FirstName,LastName);
8
9COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/004_UserAccount.sql b/OpenSim/Data/MySQL/Resources/004_UserAccount.sql
new file mode 100644
index 0000000..8abcd53
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/004_UserAccount.sql
@@ -0,0 +1,8 @@
1BEGIN;
2
3ALTER TABLE UserAccounts ADD COLUMN UserLevel integer NOT NULL DEFAULT 0;
4ALTER TABLE UserAccounts ADD COLUMN UserFlags integer NOT NULL DEFAULT 0;
5ALTER TABLE UserAccounts ADD COLUMN UserTitle varchar(64) NOT NULL DEFAULT '';
6
7COMMIT;
8
diff --git a/OpenSim/Data/MySQL/Resources/005_GridStore.sql b/OpenSim/Data/MySQL/Resources/005_GridStore.sql
new file mode 100644
index 0000000..835ba89
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/005_GridStore.sql
@@ -0,0 +1,6 @@
1BEGIN;
2
3ALTER TABLE `regions` ADD COLUMN `flags` integer NOT NULL DEFAULT 0;
4CREATE INDEX flags ON regions(flags);
5
6COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/006_GridStore.sql b/OpenSim/Data/MySQL/Resources/006_GridStore.sql
new file mode 100644
index 0000000..91322d6
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/006_GridStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE `regions` ADD COLUMN `last_seen` integer NOT NULL DEFAULT 0;
4
5COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/007_GridStore.sql b/OpenSim/Data/MySQL/Resources/007_GridStore.sql
new file mode 100644
index 0000000..dbec584
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/007_GridStore.sql
@@ -0,0 +1,7 @@
1BEGIN;
2
3ALTER TABLE `regions` ADD COLUMN `PrincipalID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
4ALTER TABLE `regions` ADD COLUMN `Token` varchar(255) NOT NULL;
5
6COMMIT;
7
diff --git a/OpenSim/Data/MySQL/Resources/032_RegionStore.sql b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql
index b10ffcf..02ac1f5 100644
--- a/OpenSim/Data/MySQL/Resources/032_RegionStore.sql
+++ b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql
@@ -67,4 +67,5 @@ CREATE TABLE `regionwindlight` (
67 PRIMARY KEY (`region_id`) 67 PRIMARY KEY (`region_id`)
68); 68);
69 69
70COMMIT; \ No newline at end of file 70ALTER TABLE estate_settings AUTO_INCREMENT = 100;
71COMMIT;
diff --git a/OpenSim/Data/MySQL/Tests/MySQLAssetTest.cs b/OpenSim/Data/MySQL/Tests/MySQLAssetTest.cs
index e1d3f81..a46fdf8 100644
--- a/OpenSim/Data/MySQL/Tests/MySQLAssetTest.cs
+++ b/OpenSim/Data/MySQL/Tests/MySQLAssetTest.cs
@@ -31,6 +31,7 @@ using OpenSim.Data.Tests;
31using log4net; 31using log4net;
32using System.Reflection; 32using System.Reflection;
33using OpenSim.Tests.Common; 33using OpenSim.Tests.Common;
34using MySql.Data.MySqlClient;
34 35
35namespace OpenSim.Data.MySQL.Tests 36namespace OpenSim.Data.MySQL.Tests
36{ 37{
@@ -39,7 +40,7 @@ namespace OpenSim.Data.MySQL.Tests
39 { 40 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 public string file; 42 public string file;
42 public MySQLManager database; 43 private string m_connectionString;
43 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;"; 44 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;";
44 45
45 [TestFixtureSetUp] 46 [TestFixtureSetUp]
@@ -52,7 +53,6 @@ namespace OpenSim.Data.MySQL.Tests
52 // tests. 53 // tests.
53 try 54 try
54 { 55 {
55 database = new MySQLManager(connect);
56 db = new MySQLAssetData(); 56 db = new MySQLAssetData();
57 db.Initialise(connect); 57 db.Initialise(connect);
58 } 58 }
@@ -70,10 +70,22 @@ namespace OpenSim.Data.MySQL.Tests
70 { 70 {
71 db.Dispose(); 71 db.Dispose();
72 } 72 }
73 if (database != null) 73 ExecuteSql("drop table migrations");
74 ExecuteSql("drop table assets");
75 }
76
77 /// <summary>
78 /// Execute a MySqlCommand
79 /// </summary>
80 /// <param name="sql">sql string to execute</param>
81 private void ExecuteSql(string sql)
82 {
83 using (MySqlConnection dbcon = new MySqlConnection(connect))
74 { 84 {
75 database.ExecuteSql("drop table migrations"); 85 dbcon.Open();
76 database.ExecuteSql("drop table assets"); 86
87 MySqlCommand cmd = new MySqlCommand(sql, dbcon);
88 cmd.ExecuteNonQuery();
77 } 89 }
78 } 90 }
79 } 91 }
diff --git a/OpenSim/Data/MySQL/Tests/MySQLEstateTest.cs b/OpenSim/Data/MySQL/Tests/MySQLEstateTest.cs
index 48486b1..01afcae 100644
--- a/OpenSim/Data/MySQL/Tests/MySQLEstateTest.cs
+++ b/OpenSim/Data/MySQL/Tests/MySQLEstateTest.cs
@@ -31,6 +31,8 @@ using OpenSim.Data.Tests;
31using log4net; 31using log4net;
32using System.Reflection; 32using System.Reflection;
33using OpenSim.Tests.Common; 33using OpenSim.Tests.Common;
34using MySql.Data.MySqlClient;
35
34 36
35namespace OpenSim.Data.MySQL.Tests 37namespace OpenSim.Data.MySQL.Tests
36{ 38{
@@ -39,7 +41,6 @@ namespace OpenSim.Data.MySQL.Tests
39 { 41 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 public string file; 43 public string file;
42 public MySQLManager database;
43 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;"; 44 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;";
44 45
45 [TestFixtureSetUp] 46 [TestFixtureSetUp]
@@ -52,9 +53,8 @@ namespace OpenSim.Data.MySQL.Tests
52 // tests. 53 // tests.
53 try 54 try
54 { 55 {
55 database = new MySQLManager(connect);
56 // clear db incase to ensure we are in a clean state 56 // clear db incase to ensure we are in a clean state
57 ClearDB(database); 57 ClearDB();
58 58
59 regionDb = new MySQLDataStore(); 59 regionDb = new MySQLDataStore();
60 regionDb.Initialise(connect); 60 regionDb.Initialise(connect);
@@ -75,29 +75,41 @@ namespace OpenSim.Data.MySQL.Tests
75 { 75 {
76 regionDb.Dispose(); 76 regionDb.Dispose();
77 } 77 }
78 ClearDB(database); 78 ClearDB();
79 } 79 }
80 80
81 private void ClearDB(MySQLManager manager) 81 private void ClearDB()
82 { 82 {
83 // if a new table is added, it has to be dropped here 83 // if a new table is added, it has to be dropped here
84 if (manager != null) 84 ExecuteSql("drop table if exists migrations");
85 ExecuteSql("drop table if exists prims");
86 ExecuteSql("drop table if exists primshapes");
87 ExecuteSql("drop table if exists primitems");
88 ExecuteSql("drop table if exists terrain");
89 ExecuteSql("drop table if exists land");
90 ExecuteSql("drop table if exists landaccesslist");
91 ExecuteSql("drop table if exists regionban");
92 ExecuteSql("drop table if exists regionsettings");
93 ExecuteSql("drop table if exists estate_managers");
94 ExecuteSql("drop table if exists estate_groups");
95 ExecuteSql("drop table if exists estate_users");
96 ExecuteSql("drop table if exists estateban");
97 ExecuteSql("drop table if exists estate_settings");
98 ExecuteSql("drop table if exists estate_map");
99 }
100
101 /// <summary>
102 /// Execute a MySqlCommand
103 /// </summary>
104 /// <param name="sql">sql string to execute</param>
105 private void ExecuteSql(string sql)
106 {
107 using (MySqlConnection dbcon = new MySqlConnection(connect))
85 { 108 {
86 manager.ExecuteSql("drop table if exists migrations"); 109 dbcon.Open();
87 manager.ExecuteSql("drop table if exists prims"); 110
88 manager.ExecuteSql("drop table if exists primshapes"); 111 MySqlCommand cmd = new MySqlCommand(sql, dbcon);
89 manager.ExecuteSql("drop table if exists primitems"); 112 cmd.ExecuteNonQuery();
90 manager.ExecuteSql("drop table if exists terrain");
91 manager.ExecuteSql("drop table if exists land");
92 manager.ExecuteSql("drop table if exists landaccesslist");
93 manager.ExecuteSql("drop table if exists regionban");
94 manager.ExecuteSql("drop table if exists regionsettings");
95 manager.ExecuteSql("drop table if exists estate_managers");
96 manager.ExecuteSql("drop table if exists estate_groups");
97 manager.ExecuteSql("drop table if exists estate_users");
98 manager.ExecuteSql("drop table if exists estateban");
99 manager.ExecuteSql("drop table if exists estate_settings");
100 manager.ExecuteSql("drop table if exists estate_map");
101 } 113 }
102 } 114 }
103 } 115 }
diff --git a/OpenSim/Data/MySQL/Tests/MySQLInventoryTest.cs b/OpenSim/Data/MySQL/Tests/MySQLInventoryTest.cs
index a3a32dc..4575493 100644
--- a/OpenSim/Data/MySQL/Tests/MySQLInventoryTest.cs
+++ b/OpenSim/Data/MySQL/Tests/MySQLInventoryTest.cs
@@ -31,6 +31,8 @@ using OpenSim.Data.Tests;
31using log4net; 31using log4net;
32using System.Reflection; 32using System.Reflection;
33using OpenSim.Tests.Common; 33using OpenSim.Tests.Common;
34using MySql.Data.MySqlClient;
35
34 36
35namespace OpenSim.Data.MySQL.Tests 37namespace OpenSim.Data.MySQL.Tests
36{ 38{
@@ -39,7 +41,6 @@ namespace OpenSim.Data.MySQL.Tests
39 { 41 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 public string file; 43 public string file;
42 public MySQLManager database;
43 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;"; 44 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;";
44 45
45 [TestFixtureSetUp] 46 [TestFixtureSetUp]
@@ -52,7 +53,6 @@ namespace OpenSim.Data.MySQL.Tests
52 // tests. 53 // tests.
53 try 54 try
54 { 55 {
55 database = new MySQLManager(connect);
56 DropTables(); 56 DropTables();
57 db = new MySQLInventoryData(); 57 db = new MySQLInventoryData();
58 db.Initialise(connect); 58 db.Initialise(connect);
@@ -71,17 +71,29 @@ namespace OpenSim.Data.MySQL.Tests
71 { 71 {
72 db.Dispose(); 72 db.Dispose();
73 } 73 }
74 if (database != null) 74 DropTables();
75 {
76 DropTables();
77 }
78 } 75 }
79 76
80 private void DropTables() 77 private void DropTables()
81 { 78 {
82 database.ExecuteSql("drop table IF EXISTS inventoryitems"); 79 ExecuteSql("drop table IF EXISTS inventoryitems");
83 database.ExecuteSql("drop table IF EXISTS inventoryfolders"); 80 ExecuteSql("drop table IF EXISTS inventoryfolders");
84 database.ExecuteSql("drop table IF EXISTS migrations"); 81 ExecuteSql("drop table IF EXISTS migrations");
82 }
83
84 /// <summary>
85 /// Execute a MySqlCommand
86 /// </summary>
87 /// <param name="sql">sql string to execute</param>
88 private void ExecuteSql(string sql)
89 {
90 using (MySqlConnection dbcon = new MySqlConnection(connect))
91 {
92 dbcon.Open();
93
94 MySqlCommand cmd = new MySqlCommand(sql, dbcon);
95 cmd.ExecuteNonQuery();
96 }
85 } 97 }
86 } 98 }
87} 99}
diff --git a/OpenSim/Data/MySQL/Tests/MySQLRegionTest.cs b/OpenSim/Data/MySQL/Tests/MySQLRegionTest.cs
index 0dc8b7d..e7e57e4 100644
--- a/OpenSim/Data/MySQL/Tests/MySQLRegionTest.cs
+++ b/OpenSim/Data/MySQL/Tests/MySQLRegionTest.cs
@@ -31,6 +31,7 @@ using OpenSim.Data.Tests;
31using log4net; 31using log4net;
32using System.Reflection; 32using System.Reflection;
33using OpenSim.Tests.Common; 33using OpenSim.Tests.Common;
34using MySql.Data.MySqlClient;
34 35
35namespace OpenSim.Data.MySQL.Tests 36namespace OpenSim.Data.MySQL.Tests
36{ 37{
@@ -39,7 +40,6 @@ namespace OpenSim.Data.MySQL.Tests
39 { 40 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 public string file; 42 public string file;
42 public MySQLManager database;
43 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;"; 43 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;";
44 44
45 [TestFixtureSetUp] 45 [TestFixtureSetUp]
@@ -52,9 +52,8 @@ namespace OpenSim.Data.MySQL.Tests
52 // tests. 52 // tests.
53 try 53 try
54 { 54 {
55 database = new MySQLManager(connect);
56 // this is important in case a previous run ended badly 55 // this is important in case a previous run ended badly
57 ClearDB(database); 56 ClearDB();
58 57
59 db = new MySQLDataStore(); 58 db = new MySQLDataStore();
60 db.Initialise(connect); 59 db.Initialise(connect);
@@ -73,28 +72,40 @@ namespace OpenSim.Data.MySQL.Tests
73 { 72 {
74 db.Dispose(); 73 db.Dispose();
75 } 74 }
76 ClearDB(database); 75 ClearDB();
77 } 76 }
78 77
79 private void ClearDB(MySQLManager manager) 78 private void ClearDB()
80 { 79 {
81 if (manager != null) 80 ExecuteSql("drop table if exists migrations");
81 ExecuteSql("drop table if exists prims");
82 ExecuteSql("drop table if exists primshapes");
83 ExecuteSql("drop table if exists primitems");
84 ExecuteSql("drop table if exists terrain");
85 ExecuteSql("drop table if exists land");
86 ExecuteSql("drop table if exists landaccesslist");
87 ExecuteSql("drop table if exists regionban");
88 ExecuteSql("drop table if exists regionsettings");
89 ExecuteSql("drop table if exists estate_managers");
90 ExecuteSql("drop table if exists estate_groups");
91 ExecuteSql("drop table if exists estate_users");
92 ExecuteSql("drop table if exists estateban");
93 ExecuteSql("drop table if exists estate_settings");
94 ExecuteSql("drop table if exists estate_map");
95 }
96
97 /// <summary>
98 /// Execute a MySqlCommand
99 /// </summary>
100 /// <param name="sql">sql string to execute</param>
101 private void ExecuteSql(string sql)
102 {
103 using (MySqlConnection dbcon = new MySqlConnection(connect))
82 { 104 {
83 manager.ExecuteSql("drop table if exists migrations"); 105 dbcon.Open();
84 manager.ExecuteSql("drop table if exists prims"); 106
85 manager.ExecuteSql("drop table if exists primshapes"); 107 MySqlCommand cmd = new MySqlCommand(sql, dbcon);
86 manager.ExecuteSql("drop table if exists primitems"); 108 cmd.ExecuteNonQuery();
87 manager.ExecuteSql("drop table if exists terrain");
88 manager.ExecuteSql("drop table if exists land");
89 manager.ExecuteSql("drop table if exists landaccesslist");
90 manager.ExecuteSql("drop table if exists regionban");
91 manager.ExecuteSql("drop table if exists regionsettings");
92 manager.ExecuteSql("drop table if exists estate_managers");
93 manager.ExecuteSql("drop table if exists estate_groups");
94 manager.ExecuteSql("drop table if exists estate_users");
95 manager.ExecuteSql("drop table if exists estateban");
96 manager.ExecuteSql("drop table if exists estate_settings");
97 manager.ExecuteSql("drop table if exists estate_map");
98 } 109 }
99 } 110 }
100 } 111 }
diff --git a/OpenSim/Data/MySQL/Tests/MySQLUserTest.cs b/OpenSim/Data/MySQL/Tests/MySQLUserTest.cs
deleted file mode 100644
index cf8139a..0000000
--- a/OpenSim/Data/MySQL/Tests/MySQLUserTest.cs
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using NUnit.Framework;
30using OpenSim.Data.Tests;
31using log4net;
32using System.Reflection;
33using OpenSim.Tests.Common;
34
35namespace OpenSim.Data.MySQL.Tests
36{
37 [TestFixture, DatabaseTest]
38 public class MySQLUserTest : BasicUserTest
39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 public string file;
42 public MySQLManager database;
43 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;";
44
45 [TestFixtureSetUp]
46 public void Init()
47 {
48 SuperInit();
49 // If we manage to connect to the database with the user
50 // and password above it is our test database, and run
51 // these tests. If anything goes wrong, ignore these
52 // tests.
53 try
54 {
55 database = new MySQLManager(connect);
56 db = new MySQLUserData();
57 db.Initialise(connect);
58 }
59 catch (Exception e)
60 {
61 m_log.Error("Exception {0}", e);
62 Assert.Ignore();
63 }
64 }
65
66 [TestFixtureTearDown]
67 public void Cleanup()
68 {
69 if (db != null)
70 {
71 db.Dispose();
72 }
73 // if a new table is added, it has to be dropped here
74 if (database != null)
75 {
76 database.ExecuteSql("drop table migrations");
77 database.ExecuteSql("drop table users");
78 database.ExecuteSql("drop table userfriends");
79 database.ExecuteSql("drop table agents");
80 database.ExecuteSql("drop table avatarappearance");
81 database.ExecuteSql("drop table avatarattachments");
82 }
83 }
84 }
85}
diff --git a/OpenSim/Grid/UserServer.Modules/GridInfoServiceModule.cs b/OpenSim/Data/Null/NullAuthenticationData.cs
index 0c84348..3fb3105 100644
--- a/OpenSim/Grid/UserServer.Modules/GridInfoServiceModule.cs
+++ b/OpenSim/Data/Null/NullAuthenticationData.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -26,54 +26,56 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using log4net;
33using log4net.Config;
34using OpenMetaverse; 31using OpenMetaverse;
35using OpenSim.Framework; 32using OpenSim.Framework;
36using OpenSim.Framework.Communications; 33using OpenSim.Data;
37using OpenSim.Framework.Communications.Services;
38using OpenSim.Framework.Communications.Cache;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Grid.Communications.OGS1;
42using OpenSim.Grid.Framework;
43 34
44namespace OpenSim.Grid.UserServer.Modules 35namespace OpenSim.Data.Null
45{ 36{
46 public class GridInfoServiceModule 37 public class NullAuthenticationData : IAuthenticationData
47 { 38 {
48 protected IGridServiceCore m_core; 39 private static Dictionary<UUID, AuthenticationData> m_DataByUUID = new Dictionary<UUID, AuthenticationData>();
49 protected GridInfoService m_gridInfoService; 40 private static Dictionary<UUID, string> m_Tokens = new Dictionary<UUID, string>();
50 protected BaseHttpServer m_httpServer;
51 41
52 public GridInfoServiceModule() 42 public NullAuthenticationData(string connectionString, string realm)
53 { 43 {
54 } 44 }
55 45
56 public void Initialise(IGridServiceCore core) 46 public AuthenticationData Get(UUID principalID)
57 { 47 {
58 m_core = core; 48 if (m_DataByUUID.ContainsKey(principalID))
59 m_gridInfoService = new GridInfoService(); 49 return m_DataByUUID[principalID];
50
51 return null;
60 } 52 }
61 53
62 public void PostInitialise() 54 public bool Store(AuthenticationData data)
63 { 55 {
56 m_DataByUUID[data.PrincipalID] = data;
57 return true;
58 }
64 59
60 public bool SetDataItem(UUID principalID, string item, string value)
61 {
62 // Not implemented
63 return false;
65 } 64 }
66 65
67 public void RegisterHandlers(BaseHttpServer httpServer) 66 public bool SetToken(UUID principalID, string token, int lifetime)
68 { 67 {
69 m_httpServer = httpServer; 68 m_Tokens[principalID] = token;
70 m_httpServer.AddStreamHandler(new RestStreamHandler("GET", "/get_grid_info", 69 return true;
71 m_gridInfoService.RestGetGridInfoMethod));
72 m_httpServer.AddXmlRPCHandler("get_grid_info", m_gridInfoService.XmlRpcGridInfoMethod);
73 } 70 }
74 71
75 public void Close() 72 public bool CheckToken(UUID principalID, string token, int lifetime)
76 { 73 {
74 if (m_Tokens.ContainsKey(principalID))
75 return m_Tokens[principalID] == token;
76
77 return false;
77 } 78 }
79
78 } 80 }
79} 81}
diff --git a/OpenSim/Grid/MessagingServer.Modules/PresenceBackreferenceEntry.cs b/OpenSim/Data/Null/NullAvatarData.cs
index 67dde6d..c81ba43 100644
--- a/OpenSim/Grid/MessagingServer.Modules/PresenceBackreferenceEntry.cs
+++ b/OpenSim/Data/Null/NullAvatarData.cs
@@ -25,72 +25,69 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Collections;
28using System.Collections.Generic; 30using System.Collections.Generic;
29using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Data;
30 34
31namespace OpenSim.Grid.MessagingServer.Modules 35namespace OpenSim.Data.Null
32{ 36{
33 // This is a wrapper for a List<UUID> so it can be happily stored in a hashtable. 37 public class NullAvatarData : IAvatarData
34 public class PresenceBackreferenceEntry
35 { 38 {
36 List<UUID> AgentList = new List<UUID>(); 39 private static Dictionary<UUID, AvatarBaseData> m_DataByUUID = new Dictionary<UUID, AvatarBaseData>();
37 40
38 public PresenceBackreferenceEntry() 41 public NullAvatarData(string connectionString, string realm)
39 { 42 {
40
41 } 43 }
42 44
43 public void Add(UUID item) 45 public AvatarBaseData[] Get(string field, string val)
44 { 46 {
45 lock (AgentList) 47 if (field == "PrincipalID")
46 { 48 {
47 AgentList.Add(item); 49 UUID id = UUID.Zero;
50 if (UUID.TryParse(val, out id))
51 if (m_DataByUUID.ContainsKey(id))
52 return new AvatarBaseData[] { m_DataByUUID[id] };
48 } 53 }
49 }
50 54
51 public UUID getitem(int index) 55 // Fail
52 { 56 return new AvatarBaseData[0];
53 UUID result = UUID.Zero;
54 lock (AgentList)
55 {
56 if (index > 0 && index < AgentList.Count)
57 {
58 result = AgentList[index];
59 }
60 }
61 return result;
62 } 57 }
63 58
64 public int Count 59 public bool Store(AvatarBaseData data)
65 { 60 {
66 get 61 m_DataByUUID[data.PrincipalID] = data;
67 { 62 return true;
68 int count = 0;
69 lock (AgentList)
70 {
71 count = AgentList.Count;
72 }
73 return count;
74 }
75 } 63 }
76 64
77 public void Remove(UUID item) 65 public bool Delete(UUID principalID, string name)
78 { 66 {
79 lock (AgentList) 67 if (m_DataByUUID.ContainsKey(principalID) && m_DataByUUID[principalID].Data.ContainsKey(name))
80 { 68 {
81 if (AgentList.Contains(item)) 69 m_DataByUUID[principalID].Data.Remove(name);
82 AgentList.Remove(item); 70 return true;
83 } 71 }
72
73 return false;
84 } 74 }
85 75
86 public bool contains(UUID item) 76 public bool Delete(string field, string val)
87 { 77 {
88 bool result = false; 78 if (field == "PrincipalID")
89 lock (AgentList)
90 { 79 {
91 result = AgentList.Contains(item); 80 UUID id = UUID.Zero;
81 if (UUID.TryParse(val, out id))
82 if (m_DataByUUID.ContainsKey(id))
83 {
84 m_DataByUUID.Remove(id);
85 return true;
86 }
92 } 87 }
93 return result; 88
89 return false;
94 } 90 }
91
95 } 92 }
96} 93}
diff --git a/OpenSim/Data/Null/NullDataStore.cs b/OpenSim/Data/Null/NullDataStore.cs
index 4b6d0f3..3ba44bb 100644
--- a/OpenSim/Data/Null/NullDataStore.cs
+++ b/OpenSim/Data/Null/NullDataStore.cs
@@ -50,13 +50,13 @@ namespace OpenSim.Data.Null
50 public void StoreRegionSettings(RegionSettings rs) 50 public void StoreRegionSettings(RegionSettings rs)
51 { 51 {
52 } 52 }
53 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) 53 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
54 { 54 {
55 //This connector doesn't support the windlight module yet 55 //This connector doesn't support the windlight module yet
56 //Return default LL windlight settings 56 //Return default LL windlight settings
57 return new RegionMeta7WindlightData(); 57 return new RegionLightShareData();
58 } 58 }
59 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) 59 public void StoreRegionWindlightSettings(RegionLightShareData wl)
60 { 60 {
61 //This connector doesn't support the windlight module yet 61 //This connector doesn't support the windlight module yet
62 } 62 }
diff --git a/OpenSim/Grid/MessagingServer.Modules/UserDataBaseService.cs b/OpenSim/Data/Null/NullFriendsData.cs
index 76c4899..e7f7fd3 100644
--- a/OpenSim/Grid/MessagingServer.Modules/UserDataBaseService.cs
+++ b/OpenSim/Data/Null/NullFriendsData.cs
@@ -25,51 +25,68 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Collections;
30using System.Collections.Generic;
28using OpenMetaverse; 31using OpenMetaverse;
29using OpenSim.Framework; 32using OpenSim.Framework;
30using OpenSim.Framework.Communications; 33using OpenSim.Data;
31 34
32namespace OpenSim.Grid.MessagingServer.Modules 35namespace OpenSim.Data.Null
33{ 36{
34 public class UserDataBaseService : UserManagerBase 37 public class NullFriendsData : IFriendsData
35 { 38 {
36 /// <summary> 39 private static List<FriendsData> m_Data = new List<FriendsData>();
37 /// Constructor. 40
38 /// </summary> 41 public NullFriendsData(string connectionString, string realm)
39 /// Passing null to parent because we never use any function that requires an interservice inventory call.
40 public UserDataBaseService()
41 : base(null)
42 { 42 {
43 } 43 }
44
45 public UserAgentData GetUserAgentData(UUID AgentID)
46 {
47 UserProfileData userProfile = GetUserProfile(AgentID);
48 44
49 if (userProfile != null) 45 /// <summary>
46 /// Tries to implement the Get [] semantics, but it cuts corners.
47 /// Specifically, it gets all friendships even if they weren't accepted yet.
48 /// </summary>
49 /// <param name="fields"></param>
50 /// <param name="values"></param>
51 /// <returns></returns>
52 public FriendsData[] GetFriends(UUID userID)
53 {
54 List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
50 { 55 {
51 return userProfile.CurrentAgent; 56 return fdata.PrincipalID == userID;
52 } 57 });
53 58
54 return null; 59 if (lst != null)
55 } 60 return lst.ToArray();
56 61
57 public override UserProfileData SetupMasterUser(string firstName, string lastName) 62 return new FriendsData[0];
58 {
59 //throw new Exception("The method or operation is not implemented.");
60 return null;
61 } 63 }
62 64
63 public override UserProfileData SetupMasterUser(string firstName, string lastName, string password) 65 public bool Store(FriendsData data)
64 { 66 {
65 //throw new Exception("The method or operation is not implemented."); 67 if (data == null)
66 return null; 68 return false;
69
70 m_Data.Add(data);
71
72 return true;
67 } 73 }
68 74
69 public override UserProfileData SetupMasterUser(UUID uuid) 75 public bool Delete(UUID userID, string friendID)
70 { 76 {
71 //throw new Exception("The method or operation is not implemented."); 77 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; });
72 return null; 78 if (lst != null)
79 {
80 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
81 if (friendID != null)
82 {
83 m_Data.Remove(friend);
84 return true;
85 }
86 }
87
88 return false;
73 } 89 }
90
74 } 91 }
75} 92}
diff --git a/OpenSim/Data/Null/NullInventoryData.cs b/OpenSim/Data/Null/NullInventoryData.cs
new file mode 100644
index 0000000..8f196e2
--- /dev/null
+++ b/OpenSim/Data/Null/NullInventoryData.cs
@@ -0,0 +1,193 @@
1using System;
2using System.Collections.Generic;
3
4using OpenMetaverse;
5using OpenSim.Framework;
6
7namespace OpenSim.Data.Null
8{
9 /// <summary>
10 /// This class is completely null.
11 /// </summary>
12 public class NullInventoryData : IInventoryDataPlugin
13 {
14 public string Version { get { return "1.0.0.0"; } }
15
16 public void Initialise()
17 {
18 }
19
20 public void Dispose()
21 {
22 // Do nothing.
23 }
24
25 public string Name
26 {
27 get { return "Null Inventory Data Interface"; }
28 }
29
30 public void Initialise(string connect)
31 {
32 }
33
34
35 /// <summary>
36 /// Returns all descendent folders of this folder. Does not return the parent folder itself.
37 /// </summary>
38 /// <param name="parentID">The folder to get subfolders for</param>
39 /// <returns>A list of inventory folders</returns>
40 public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
41 {
42 return new List<InventoryFolderBase>();
43 }
44
45 /// <summary>
46 /// Returns a list of inventory items contained within the specified folder
47 /// </summary>
48 /// <param name="folderID">The UUID of the target folder</param>
49 /// <returns>A List of InventoryItemBase items</returns>
50 public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
51 {
52 return new List<InventoryItemBase>();
53 }
54
55 /// <summary>
56 /// Returns a list of the root folders within a users inventory
57 /// </summary>
58 /// <param name="user">The user whos inventory is to be searched</param>
59 /// <returns>A list of folder objects</returns>
60 public List<InventoryFolderBase> getUserRootFolders(UUID user)
61 {
62 return new List<InventoryFolderBase>();
63 }
64
65 /// <summary>
66 /// Returns the users inventory root folder.
67 /// </summary>
68 /// <param name="user">The UUID of the user who is having inventory being returned</param>
69 /// <returns>Root inventory folder, null if no root inventory folder was found</returns>
70 public InventoryFolderBase getUserRootFolder(UUID user)
71 {
72 return null;
73 }
74
75 /// <summary>
76 /// Returns a list of inventory folders contained in the folder 'parentID'
77 /// </summary>
78 /// <param name="parentID">The folder to get subfolders for</param>
79 /// <returns>A list of inventory folders</returns>
80 public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
81 {
82 return new List<InventoryFolderBase>();
83 }
84
85 /// <summary>
86 /// Returns an inventory item by its UUID
87 /// </summary>
88 /// <param name="item">The UUID of the item to be returned</param>
89 /// <returns>A class containing item information</returns>
90 public InventoryItemBase getInventoryItem(UUID item)
91 {
92 return null;
93 }
94
95 /// <summary>
96 /// Returns a specified inventory folder by its UUID
97 /// </summary>
98 /// <param name="folder">The UUID of the folder to be returned</param>
99 /// <returns>A class containing folder information</returns>
100 public InventoryFolderBase getInventoryFolder(UUID folder)
101 {
102 return null;
103 }
104
105 /// <summary>
106 /// Creates a new inventory item based on item
107 /// </summary>
108 /// <param name="item">The item to be created</param>
109 public void addInventoryItem(InventoryItemBase item)
110 {
111 }
112
113 /// <summary>
114 /// Updates an inventory item with item (updates based on ID)
115 /// </summary>
116 /// <param name="item">The updated item</param>
117 public void updateInventoryItem(InventoryItemBase item)
118 {
119 }
120
121 /// <summary>
122 ///
123 /// </summary>
124 /// <param name="item"></param>
125 public void deleteInventoryItem(UUID item)
126 {
127 }
128
129 /// <summary>
130 ///
131 /// </summary>
132 /// <param name="item"></param>
133 public InventoryItemBase queryInventoryItem(UUID item)
134 {
135 return null;
136 }
137
138 /// <summary>
139 ///
140 /// </summary>
141 /// <param name="item"></param>
142 public InventoryFolderBase queryInventoryFolder(UUID folder)
143 {
144 return null;
145 }
146
147 /// <summary>
148 /// Adds a new folder specified by folder
149 /// </summary>
150 /// <param name="folder">The inventory folder</param>
151 public void addInventoryFolder(InventoryFolderBase folder)
152 {
153 }
154
155 /// <summary>
156 /// Updates a folder based on its ID with folder
157 /// </summary>
158 /// <param name="folder">The inventory folder</param>
159 public void updateInventoryFolder(InventoryFolderBase folder)
160 {
161 }
162
163 /// <summary>
164 /// Updates a folder based on its ID with folder
165 /// </summary>
166 /// <param name="folder">The inventory folder</param>
167 public void moveInventoryFolder(InventoryFolderBase folder)
168 {
169 }
170
171 /// <summary>
172 /// Deletes a folder. Thie will delete both the folder itself and its contents (items and descendent folders)
173 /// </summary>
174 /// <param name="folder">The id of the folder</param>
175 public void deleteInventoryFolder(UUID folder)
176 {
177 }
178
179 /// <summary>
180 /// Returns all activated gesture-items in the inventory of the specified avatar.
181 /// </summary>
182 /// <param name="avatarID">
183 /// The <see cref="UUID"/> of the avatar
184 /// </param>
185 /// <returns>
186 /// The list of gestures (<see cref="InventoryItemBase"/>s)
187 /// </returns>
188 public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
189 {
190 return new List<InventoryItemBase>();
191 }
192 }
193}
diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs
new file mode 100644
index 0000000..b98b5c9
--- /dev/null
+++ b/OpenSim/Data/Null/NullPresenceData.cs
@@ -0,0 +1,285 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Data;
36
37namespace OpenSim.Data.Null
38{
39 public class NullPresenceData : IPresenceData
40 {
41// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42
43 private static NullPresenceData Instance;
44
45 Dictionary<UUID, PresenceData> m_presenceData = new Dictionary<UUID, PresenceData>();
46
47 public NullPresenceData(string connectionString, string realm)
48 {
49 if (Instance == null)
50 {
51 Instance = this;
52
53 //Console.WriteLine("[XXX] NullRegionData constructor");
54 }
55 }
56
57 public bool Store(PresenceData data)
58 {
59 if (Instance != this)
60 return Instance.Store(data);
61
62// m_log.DebugFormat("[NULL PRESENCE DATA]: Storing presence {0}", data.UserID);
63// Console.WriteLine("HOME for " + data.UserID + " is " + (data.Data.ContainsKey("HomeRegionID") ? data.Data["HomeRegionID"] : "Not found"));
64
65 m_presenceData[data.SessionID] = data;
66 return true;
67 }
68
69 public PresenceData Get(UUID sessionID)
70 {
71 if (Instance != this)
72 return Instance.Get(sessionID);
73
74 if (m_presenceData.ContainsKey(sessionID))
75 {
76 return m_presenceData[sessionID];
77 }
78
79 return null;
80 }
81
82 public void LogoutRegionAgents(UUID regionID)
83 {
84 if (Instance != this)
85 {
86 Instance.LogoutRegionAgents(regionID);
87 return;
88 }
89
90 List<UUID> toBeDeleted = new List<UUID>();
91 foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData)
92 if (kvp.Value.RegionID == regionID)
93 toBeDeleted.Add(kvp.Key);
94
95 foreach (UUID u in toBeDeleted)
96 m_presenceData.Remove(u);
97 }
98
99 public bool ReportAgent(UUID sessionID, UUID regionID, string position, string lookAt)
100 {
101 if (Instance != this)
102 return Instance.ReportAgent(sessionID, regionID, position, lookAt);
103
104 if (m_presenceData.ContainsKey(sessionID))
105 {
106 m_presenceData[sessionID].RegionID = regionID;
107 m_presenceData[sessionID].Data["Position"] = position;
108 m_presenceData[sessionID].Data["LookAt"] = lookAt;
109 return true;
110 }
111
112 return false;
113 }
114
115 public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
116 {
117 if (Instance != this)
118 return Instance.SetHomeLocation(userID, regionID, position, lookAt);
119
120 bool foundone = false;
121 foreach (PresenceData p in m_presenceData.Values)
122 {
123 if (p.UserID == userID)
124 {
125// m_log.DebugFormat(
126// "[NULL PRESENCE DATA]: Setting home location {0} {1} {2} for {3}",
127// regionID, position, lookAt, p.UserID);
128
129 p.Data["HomeRegionID"] = regionID.ToString();
130 p.Data["HomePosition"] = position.ToString();
131 p.Data["HomeLookAt"] = lookAt.ToString();
132 foundone = true;
133 }
134 }
135
136 return foundone;
137 }
138
139 public PresenceData[] Get(string field, string data)
140 {
141 if (Instance != this)
142 return Instance.Get(field, data);
143
144// m_log.DebugFormat(
145// "[NULL PRESENCE DATA]: Getting presence data for field {0} with parameter {1}", field, data);
146
147 List<PresenceData> presences = new List<PresenceData>();
148 if (field == "UserID")
149 {
150 foreach (PresenceData p in m_presenceData.Values)
151 {
152 if (p.UserID == data)
153 {
154 presences.Add(p);
155// Console.WriteLine("HOME for " + p.UserID + " is " + (p.Data.ContainsKey("HomeRegionID") ? p.Data["HomeRegionID"] : "Not found"));
156 }
157 }
158
159 return presences.ToArray();
160 }
161 else if (field == "SessionID")
162 {
163 UUID session = UUID.Zero;
164 if (!UUID.TryParse(data, out session))
165 return presences.ToArray();
166
167 if (m_presenceData.ContainsKey(session))
168 {
169 presences.Add(m_presenceData[session]);
170 return presences.ToArray();
171 }
172 }
173 else if (field == "RegionID")
174 {
175 UUID region = UUID.Zero;
176 if (!UUID.TryParse(data, out region))
177 return presences.ToArray();
178 foreach (PresenceData p in m_presenceData.Values)
179 if (p.RegionID == region)
180 presences.Add(p);
181 return presences.ToArray();
182 }
183 else
184 {
185 foreach (PresenceData p in m_presenceData.Values)
186 {
187 if (p.Data.ContainsKey(field) && p.Data[field] == data)
188 presences.Add(p);
189 }
190 return presences.ToArray();
191 }
192
193 return presences.ToArray();
194 }
195
196 public void Prune(string userID)
197 {
198 if (Instance != this)
199 {
200 Instance.Prune(userID);
201 return;
202 }
203
204// m_log.DebugFormat("[NULL PRESENCE DATA]: Prune called for {0}", userID);
205
206 List<UUID> deleteSessions = new List<UUID>();
207 int online = 0;
208
209 foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData)
210 {
211// m_log.DebugFormat("Online: {0}", kvp.Value.Data["Online"]);
212
213 bool on = false;
214 if (bool.TryParse(kvp.Value.Data["Online"], out on) && on)
215 online++;
216 else
217 deleteSessions.Add(kvp.Key);
218 }
219
220// m_log.DebugFormat("[NULL PRESENCE DATA]: online [{0}], deleteSession.Count [{1}]", online, deleteSessions.Count);
221
222 // Leave one session behind so that we can pick up details such as home location
223 if (online == 0 && deleteSessions.Count > 0)
224 deleteSessions.RemoveAt(0);
225
226 foreach (UUID s in deleteSessions)
227 m_presenceData.Remove(s);
228 }
229
230 public bool Delete(string field, string data)
231 {
232// m_log.DebugFormat(
233// "[NULL PRESENCE DATA]: Deleting presence data for field {0} with parameter {1}", field, data);
234
235 if (Instance != this)
236 return Instance.Delete(field, data);
237
238 List<UUID> presences = new List<UUID>();
239 if (field == "UserID")
240 {
241 foreach (KeyValuePair<UUID, PresenceData> p in m_presenceData)
242 if (p.Value.UserID == data)
243 presences.Add(p.Key);
244 }
245 else if (field == "SessionID")
246 {
247 UUID session = UUID.Zero;
248 if (UUID.TryParse(data, out session))
249 {
250 if (m_presenceData.ContainsKey(session))
251 {
252 presences.Add(session);
253 }
254 }
255 }
256 else if (field == "RegionID")
257 {
258 UUID region = UUID.Zero;
259 if (UUID.TryParse(data, out region))
260 {
261 foreach (KeyValuePair<UUID, PresenceData> p in m_presenceData)
262 if (p.Value.RegionID == region)
263 presences.Add(p.Key);
264 }
265 }
266 else
267 {
268 foreach (KeyValuePair<UUID, PresenceData> p in m_presenceData)
269 {
270 if (p.Value.Data.ContainsKey(field) && p.Value.Data[field] == data)
271 presences.Add(p.Key);
272 }
273 }
274
275 foreach (UUID u in presences)
276 m_presenceData.Remove(u);
277
278 if (presences.Count == 0)
279 return false;
280
281 return true;
282 }
283
284 }
285}
diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs
index e8263ea..30ad747 100644
--- a/OpenSim/Data/Null/NullRegionData.cs
+++ b/OpenSim/Data/Null/NullRegionData.cs
@@ -31,20 +31,31 @@ using System.Collections.Generic;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Data; 33using OpenSim.Data;
34using System.Reflection;
35using log4net;
34 36
35namespace OpenSim.Data.Null 37namespace OpenSim.Data.Null
36{ 38{
37 public class NullRegionData : IRegionData 39 public class NullRegionData : IRegionData
38 { 40 {
41 private static NullRegionData Instance = null;
42
43// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
39 Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>(); 45 Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>();
40 46
41 public NullRegionData(string connectionString, string realm) 47 public NullRegionData(string connectionString, string realm)
42 { 48 {
49 if (Instance == null)
50 Instance = this;
43 //Console.WriteLine("[XXX] NullRegionData constructor"); 51 //Console.WriteLine("[XXX] NullRegionData constructor");
44 } 52 }
45 53
46 public List<RegionData> Get(string regionName, UUID scopeID) 54 public List<RegionData> Get(string regionName, UUID scopeID)
47 { 55 {
56 if (Instance != this)
57 return Instance.Get(regionName, scopeID);
58
48 List<RegionData> ret = new List<RegionData>(); 59 List<RegionData> ret = new List<RegionData>();
49 60
50 foreach (RegionData r in m_regionData.Values) 61 foreach (RegionData r in m_regionData.Values)
@@ -69,6 +80,9 @@ namespace OpenSim.Data.Null
69 80
70 public RegionData Get(int posX, int posY, UUID scopeID) 81 public RegionData Get(int posX, int posY, UUID scopeID)
71 { 82 {
83 if (Instance != this)
84 return Instance.Get(posX, posY, scopeID);
85
72 List<RegionData> ret = new List<RegionData>(); 86 List<RegionData> ret = new List<RegionData>();
73 87
74 foreach (RegionData r in m_regionData.Values) 88 foreach (RegionData r in m_regionData.Values)
@@ -85,6 +99,9 @@ namespace OpenSim.Data.Null
85 99
86 public RegionData Get(UUID regionID, UUID scopeID) 100 public RegionData Get(UUID regionID, UUID scopeID)
87 { 101 {
102 if (Instance != this)
103 return Instance.Get(regionID, scopeID);
104
88 if (m_regionData.ContainsKey(regionID)) 105 if (m_regionData.ContainsKey(regionID))
89 return m_regionData[regionID]; 106 return m_regionData[regionID];
90 107
@@ -93,6 +110,9 @@ namespace OpenSim.Data.Null
93 110
94 public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID) 111 public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
95 { 112 {
113 if (Instance != this)
114 return Instance.Get(startX, startY, endX, endY, scopeID);
115
96 List<RegionData> ret = new List<RegionData>(); 116 List<RegionData> ret = new List<RegionData>();
97 117
98 foreach (RegionData r in m_regionData.Values) 118 foreach (RegionData r in m_regionData.Values)
@@ -106,6 +126,9 @@ namespace OpenSim.Data.Null
106 126
107 public bool Store(RegionData data) 127 public bool Store(RegionData data)
108 { 128 {
129 if (Instance != this)
130 return Instance.Store(data);
131
109 m_regionData[data.RegionID] = data; 132 m_regionData[data.RegionID] = data;
110 133
111 return true; 134 return true;
@@ -113,6 +136,9 @@ namespace OpenSim.Data.Null
113 136
114 public bool SetDataItem(UUID regionID, string item, string value) 137 public bool SetDataItem(UUID regionID, string item, string value)
115 { 138 {
139 if (Instance != this)
140 return Instance.SetDataItem(regionID, item, value);
141
116 if (!m_regionData.ContainsKey(regionID)) 142 if (!m_regionData.ContainsKey(regionID))
117 return false; 143 return false;
118 144
@@ -123,6 +149,9 @@ namespace OpenSim.Data.Null
123 149
124 public bool Delete(UUID regionID) 150 public bool Delete(UUID regionID)
125 { 151 {
152 if (Instance != this)
153 return Instance.Delete(regionID);
154
126 if (!m_regionData.ContainsKey(regionID)) 155 if (!m_regionData.ContainsKey(regionID))
127 return false; 156 return false;
128 157
@@ -130,5 +159,37 @@ namespace OpenSim.Data.Null
130 159
131 return true; 160 return true;
132 } 161 }
162
163 public List<RegionData> GetDefaultRegions(UUID scopeID)
164 {
165 if (Instance != this)
166 return Instance.GetDefaultRegions(scopeID);
167
168 List<RegionData> ret = new List<RegionData>();
169
170 foreach (RegionData r in m_regionData.Values)
171 {
172 if ((Convert.ToInt32(r.Data["flags"]) & 1) != 0)
173 ret.Add(r);
174 }
175
176 return ret;
177 }
178
179 public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
180 {
181 if (Instance != this)
182 return Instance.GetFallbackRegions(scopeID, x, y);
183
184 List<RegionData> ret = new List<RegionData>();
185
186 foreach (RegionData r in m_regionData.Values)
187 {
188 if ((Convert.ToInt32(r.Data["flags"]) & 2) != 0)
189 ret.Add(r);
190 }
191
192 return ret;
193 }
133 } 194 }
134} 195} \ No newline at end of file
diff --git a/OpenSim/Data/Null/NullUserAccountData.cs b/OpenSim/Data/Null/NullUserAccountData.cs
new file mode 100644
index 0000000..9eb94e6
--- /dev/null
+++ b/OpenSim/Data/Null/NullUserAccountData.cs
@@ -0,0 +1,160 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Data;
34
35namespace OpenSim.Data.Null
36{
37 public class NullUserAccountData : IUserAccountData
38 {
39 private static Dictionary<UUID, UserAccountData> m_DataByUUID = new Dictionary<UUID, UserAccountData>();
40 private static Dictionary<string, UserAccountData> m_DataByName = new Dictionary<string, UserAccountData>();
41 private static Dictionary<string, UserAccountData> m_DataByEmail = new Dictionary<string, UserAccountData>();
42
43 public NullUserAccountData(string connectionString, string realm)
44 {
45 }
46
47 /// <summary>
48 /// Tries to implement the Get [] semantics, but it cuts corners like crazy.
49 /// Specifically, it relies on the knowledge that the only Gets used are
50 /// keyed on PrincipalID, Email, and FirstName+LastName.
51 /// </summary>
52 /// <param name="fields"></param>
53 /// <param name="values"></param>
54 /// <returns></returns>
55 public UserAccountData[] Get(string[] fields, string[] values)
56 {
57 List<string> fieldsLst = new List<string>(fields);
58 if (fieldsLst.Contains("PrincipalID"))
59 {
60 int i = fieldsLst.IndexOf("PrincipalID");
61 UUID id = UUID.Zero;
62 if (UUID.TryParse(values[i], out id))
63 if (m_DataByUUID.ContainsKey(id))
64 return new UserAccountData[] { m_DataByUUID[id] };
65 }
66 if (fieldsLst.Contains("FirstName") && fieldsLst.Contains("LastName"))
67 {
68 int findex = fieldsLst.IndexOf("FirstName");
69 int lindex = fieldsLst.IndexOf("LastName");
70 if (m_DataByName.ContainsKey(values[findex] + " " + values[lindex]))
71 return new UserAccountData[] { m_DataByName[values[findex] + " " + values[lindex]] };
72 }
73 if (fieldsLst.Contains("Email"))
74 {
75 int i = fieldsLst.IndexOf("Email");
76 if (m_DataByEmail.ContainsKey(values[i]))
77 return new UserAccountData[] { m_DataByEmail[values[i]] };
78 }
79
80 // Fail
81 return new UserAccountData[0];
82 }
83
84 public bool Store(UserAccountData data)
85 {
86 if (data == null)
87 return false;
88
89 m_DataByUUID[data.PrincipalID] = data;
90 m_DataByName[data.FirstName + " " + data.LastName] = data;
91 if (data.Data.ContainsKey("Email") && data.Data["Email"] != string.Empty)
92 m_DataByEmail[data.Data["Email"]] = data;
93
94 return true;
95 }
96
97 public UserAccountData[] GetUsers(UUID scopeID, string query)
98 {
99 string[] words = query.Split(new char[] { ' ' });
100
101 for (int i = 0; i < words.Length; i++)
102 {
103 if (words[i].Length < 3)
104 {
105 if (i != words.Length - 1)
106 Array.Copy(words, i + 1, words, i, words.Length - i - 1);
107 Array.Resize(ref words, words.Length - 1);
108 }
109 }
110
111 if (words.Length == 0)
112 return new UserAccountData[0];
113
114 if (words.Length > 2)
115 return new UserAccountData[0];
116
117 List<string> lst = new List<string>(m_DataByName.Keys);
118 if (words.Length == 1)
119 {
120 lst = lst.FindAll(delegate(string s) { return s.StartsWith(words[0]); });
121 }
122 else
123 {
124 lst = lst.FindAll(delegate(string s) { return s.Contains(words[0]) || s.Contains(words[1]); });
125 }
126
127 if (lst == null || (lst != null && lst.Count == 0))
128 return new UserAccountData[0];
129
130 UserAccountData[] result = new UserAccountData[lst.Count];
131 int n = 0;
132 foreach (string key in lst)
133 result[n++] = m_DataByName[key];
134
135 return result;
136 }
137
138 public bool Delete(string field, string val)
139 {
140 // Only delete by PrincipalID
141 if (field.Equals("PrincipalID"))
142 {
143 UUID uuid = UUID.Zero;
144 if (UUID.TryParse(val, out uuid) && m_DataByUUID.ContainsKey(uuid))
145 {
146 UserAccountData account = m_DataByUUID[uuid];
147 m_DataByUUID.Remove(uuid);
148 if (m_DataByName.ContainsKey(account.FirstName + " " + account.LastName))
149 m_DataByName.Remove(account.FirstName + " " + account.LastName);
150 if (account.Data.ContainsKey("Email") && account.Data["Email"] != string.Empty && m_DataByEmail.ContainsKey(account.Data["Email"]))
151 m_DataByEmail.Remove(account.Data["Email"]);
152
153 return true;
154 }
155 }
156
157 return false;
158 }
159 }
160}
diff --git a/OpenSim/Data/RegionProfileData.cs b/OpenSim/Data/RegionProfileData.cs
deleted file mode 100644
index 86d7f6b..0000000
--- a/OpenSim/Data/RegionProfileData.cs
+++ /dev/null
@@ -1,338 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using Nwc.XmlRpc;
31using OpenMetaverse;
32using OpenSim.Framework;
33
34namespace OpenSim.Data
35{
36 /// <summary>
37 /// A class which contains information known to the grid server about a region
38 /// </summary>
39 [Serializable]
40 public class RegionProfileData
41 {
42 /// <summary>
43 /// The name of the region
44 /// </summary>
45 public string regionName = String.Empty;
46
47 /// <summary>
48 /// A 64-bit number combining map position into a (mostly) unique ID
49 /// </summary>
50 public ulong regionHandle;
51
52 /// <summary>
53 /// OGS/OpenSim Specific ID for a region
54 /// </summary>
55 public UUID UUID;
56
57 /// <summary>
58 /// Coordinates of the region
59 /// </summary>
60 public uint regionLocX;
61 public uint regionLocY;
62 public uint regionLocZ; // Reserved (round-robin, layers, etc)
63
64 /// <summary>
65 /// Authentication secrets
66 /// </summary>
67 /// <remarks>Not very secure, needs improvement.</remarks>
68 public string regionSendKey = String.Empty;
69 public string regionRecvKey = String.Empty;
70 public string regionSecret = String.Empty;
71
72 /// <summary>
73 /// Whether the region is online
74 /// </summary>
75 public bool regionOnline;
76
77 /// <summary>
78 /// Information about the server that the region is currently hosted on
79 /// </summary>
80 public string serverIP = String.Empty;
81 public uint serverPort;
82 public string serverURI = String.Empty;
83
84 public uint httpPort;
85 public uint remotingPort;
86 public string httpServerURI = String.Empty;
87
88 /// <summary>
89 /// Set of optional overrides. Can be used to create non-eulicidean spaces.
90 /// </summary>
91 public ulong regionNorthOverrideHandle;
92 public ulong regionSouthOverrideHandle;
93 public ulong regionEastOverrideHandle;
94 public ulong regionWestOverrideHandle;
95
96 /// <summary>
97 /// Optional: URI Location of the region database
98 /// </summary>
99 /// <remarks>Used for floating sim pools where the region data is not nessecarily coupled to a specific server</remarks>
100 public string regionDataURI = String.Empty;
101
102 /// <summary>
103 /// Region Asset Details
104 /// </summary>
105 public string regionAssetURI = String.Empty;
106
107 public string regionAssetSendKey = String.Empty;
108 public string regionAssetRecvKey = String.Empty;
109
110 /// <summary>
111 /// Region Userserver Details
112 /// </summary>
113 public string regionUserURI = String.Empty;
114
115 public string regionUserSendKey = String.Empty;
116 public string regionUserRecvKey = String.Empty;
117
118 /// <summary>
119 /// Region Map Texture Asset
120 /// </summary>
121 public UUID regionMapTextureID = new UUID("00000000-0000-1111-9999-000000000006");
122
123 /// <summary>
124 /// this particular mod to the file provides support within the spec for RegionProfileData for the
125 /// owner_uuid for the region
126 /// </summary>
127 public UUID owner_uuid = UUID.Zero;
128
129 /// <summary>
130 /// OGS/OpenSim Specific original ID for a region after move/split
131 /// </summary>
132 public UUID originUUID;
133
134 /// <summary>
135 /// The Maturity rating of the region
136 /// </summary>
137 public uint maturity;
138
139
140 //Data Wrappers
141 public string RegionName
142 {
143 get { return regionName; }
144 set { regionName = value; }
145 }
146 public ulong RegionHandle
147 {
148 get { return regionHandle; }
149 set { regionHandle = value; }
150 }
151 public UUID Uuid
152 {
153 get { return UUID; }
154 set { UUID = value; }
155 }
156 public uint RegionLocX
157 {
158 get { return regionLocX; }
159 set { regionLocX = value; }
160 }
161 public uint RegionLocY
162 {
163 get { return regionLocY; }
164 set { regionLocY = value; }
165 }
166 public uint RegionLocZ
167 {
168 get { return regionLocZ; }
169 set { regionLocZ = value; }
170 }
171 public string RegionSendKey
172 {
173 get { return regionSendKey; }
174 set { regionSendKey = value; }
175 }
176 public string RegionRecvKey
177 {
178 get { return regionRecvKey; }
179 set { regionRecvKey = value; }
180 }
181 public string RegionSecret
182 {
183 get { return regionSecret; }
184 set { regionSecret = value; }
185 }
186 public bool RegionOnline
187 {
188 get { return regionOnline; }
189 set { regionOnline = value; }
190 }
191 public string ServerIP
192 {
193 get { return serverIP; }
194 set { serverIP = value; }
195 }
196 public uint ServerPort
197 {
198 get { return serverPort; }
199 set { serverPort = value; }
200 }
201 public string ServerURI
202 {
203 get { return serverURI; }
204 set { serverURI = value; }
205 }
206 public uint ServerHttpPort
207 {
208 get { return httpPort; }
209 set { httpPort = value; }
210 }
211 public uint ServerRemotingPort
212 {
213 get { return remotingPort; }
214 set { remotingPort = value; }
215 }
216
217 public ulong NorthOverrideHandle
218 {
219 get { return regionNorthOverrideHandle; }
220 set { regionNorthOverrideHandle = value; }
221 }
222 public ulong SouthOverrideHandle
223 {
224 get { return regionSouthOverrideHandle; }
225 set { regionSouthOverrideHandle = value; }
226 }
227 public ulong EastOverrideHandle
228 {
229 get { return regionEastOverrideHandle; }
230 set { regionEastOverrideHandle = value; }
231 }
232 public ulong WestOverrideHandle
233 {
234 get { return regionWestOverrideHandle; }
235 set { regionWestOverrideHandle = value; }
236 }
237 public string RegionDataURI
238 {
239 get { return regionDataURI; }
240 set { regionDataURI = value; }
241 }
242 public string RegionAssetURI
243 {
244 get { return regionAssetURI; }
245 set { regionAssetURI = value; }
246 }
247 public string RegionAssetSendKey
248 {
249 get { return regionAssetSendKey; }
250 set { regionAssetSendKey = value; }
251 }
252 public string RegionAssetRecvKey
253 {
254 get { return regionAssetRecvKey; }
255 set { regionAssetRecvKey = value; }
256 }
257 public string RegionUserURI
258 {
259 get { return regionUserURI; }
260 set { regionUserURI = value; }
261 }
262 public string RegionUserSendKey
263 {
264 get { return regionUserSendKey; }
265 set { regionUserSendKey = value; }
266 }
267 public string RegionUserRecvKey
268 {
269 get { return regionUserRecvKey; }
270 set { regionUserRecvKey = value; }
271 }
272 public UUID RegionMapTextureID
273 {
274 get { return regionMapTextureID; }
275 set { regionMapTextureID = value; }
276 }
277 public UUID Owner_uuid
278 {
279 get { return owner_uuid; }
280 set { owner_uuid = value; }
281 }
282 public UUID OriginUUID
283 {
284 get { return originUUID; }
285 set { originUUID = value; }
286 }
287 public uint Maturity
288 {
289 get { return maturity; }
290 set { maturity = value; }
291 }
292
293 public byte AccessLevel
294 {
295 get { return Util.ConvertMaturityToAccessLevel(maturity); }
296 }
297
298
299 public RegionInfo ToRegionInfo()
300 {
301 return RegionInfo.Create(UUID, regionName, regionLocX, regionLocY, serverIP, httpPort, serverPort, remotingPort, serverURI);
302 }
303
304 public static RegionProfileData FromRegionInfo(RegionInfo regionInfo)
305 {
306 if (regionInfo == null)
307 {
308 return null;
309 }
310
311 return Create(regionInfo.RegionID, regionInfo.RegionName, regionInfo.RegionLocX,
312 regionInfo.RegionLocY, regionInfo.ExternalHostName,
313 (uint) regionInfo.ExternalEndPoint.Port, regionInfo.HttpPort, regionInfo.RemotingPort,
314 regionInfo.ServerURI, regionInfo.AccessLevel);
315 }
316
317 public static RegionProfileData Create(UUID regionID, string regionName, uint locX, uint locY, string externalHostName, uint regionPort, uint httpPort, uint remotingPort, string serverUri, byte access)
318 {
319 RegionProfileData regionProfile;
320 regionProfile = new RegionProfileData();
321 regionProfile.regionLocX = locX;
322 regionProfile.regionLocY = locY;
323 regionProfile.regionHandle =
324 Utils.UIntsToLong((regionProfile.regionLocX * Constants.RegionSize),
325 (regionProfile.regionLocY*Constants.RegionSize));
326 regionProfile.serverIP = externalHostName;
327 regionProfile.serverPort = regionPort;
328 regionProfile.httpPort = httpPort;
329 regionProfile.remotingPort = remotingPort;
330 regionProfile.serverURI = serverUri;
331 regionProfile.httpServerURI = "http://" + externalHostName + ":" + httpPort + "/";
332 regionProfile.UUID = regionID;
333 regionProfile.regionName = regionName;
334 regionProfile.maturity = access;
335 return regionProfile;
336 }
337 }
338}
diff --git a/OpenSim/Data/RegionProfileServiceProxy.cs b/OpenSim/Data/RegionProfileServiceProxy.cs
deleted file mode 100644
index 20d7df0..0000000
--- a/OpenSim/Data/RegionProfileServiceProxy.cs
+++ /dev/null
@@ -1,119 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Text;
32using Nwc.XmlRpc;
33using OpenMetaverse;
34using OpenSim.Framework;
35
36namespace OpenSim.Data
37{
38 public class RegionProfileServiceProxy : IRegionProfileRouter
39 {
40 /// <summary>
41 /// Request sim data based on arbitrary key/value
42 /// </summary>
43 private RegionProfileData RequestSimData(Uri gridserverUrl, string gridserverSendkey, string keyField, string keyValue)
44 {
45 Hashtable requestData = new Hashtable();
46 requestData[keyField] = keyValue;
47 requestData["authkey"] = gridserverSendkey;
48 ArrayList SendParams = new ArrayList();
49 SendParams.Add(requestData);
50 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
51 XmlRpcResponse GridResp = GridReq.Send(gridserverUrl.ToString(), 3000);
52
53 Hashtable responseData = (Hashtable) GridResp.Value;
54
55 RegionProfileData simData = null;
56
57 if (!responseData.ContainsKey("error"))
58 {
59 uint locX = Convert.ToUInt32((string)responseData["region_locx"]);
60 uint locY = Convert.ToUInt32((string)responseData["region_locy"]);
61 string externalHostName = (string)responseData["sim_ip"];
62 uint simPort = Convert.ToUInt32((string)responseData["sim_port"]);
63 uint httpPort = Convert.ToUInt32((string)responseData["http_port"]);
64 uint remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]);
65 string serverUri = (string)responseData["server_uri"];
66 UUID regionID = new UUID((string)responseData["region_UUID"]);
67 string regionName = (string)responseData["region_name"];
68 byte access = Convert.ToByte((string)responseData["access"]);
69
70 simData = RegionProfileData.Create(regionID, regionName, locX, locY, externalHostName, simPort, httpPort, remotingPort, serverUri, access);
71 }
72
73 return simData;
74 }
75
76 /// <summary>
77 /// Request sim profile information from a grid server, by Region UUID
78 /// </summary>
79 /// <param name="regionId">The region UUID to look for</param>
80 /// <param name="gridserverUrl"></param>
81 /// <param name="gridserverSendkey"></param>
82 /// <param name="gridserverRecvkey"></param>
83 /// <returns>The sim profile. Null if there was a request failure</returns>
84 /// <remarks>This method should be statics</remarks>
85 public RegionProfileData RequestSimProfileData(UUID regionId, Uri gridserverUrl,
86 string gridserverSendkey, string gridserverRecvkey)
87 {
88 return RequestSimData(gridserverUrl, gridserverSendkey, "region_UUID", regionId.Guid.ToString());
89 }
90
91 /// <summary>
92 /// Request sim profile information from a grid server, by Region Handle
93 /// </summary>
94 /// <param name="regionHandle">the region handle to look for</param>
95 /// <param name="gridserverUrl"></param>
96 /// <param name="gridserverSendkey"></param>
97 /// <param name="gridserverRecvkey"></param>
98 /// <returns>The sim profile. Null if there was a request failure</returns>
99 public RegionProfileData RequestSimProfileData(ulong regionHandle, Uri gridserverUrl,
100 string gridserverSendkey, string gridserverRecvkey)
101 {
102 return RequestSimData(gridserverUrl, gridserverSendkey, "region_handle", regionHandle.ToString());
103 }
104
105 /// <summary>
106 /// Request sim profile information from a grid server, by Region Name
107 /// </summary>
108 /// <param name="regionName">the region name to look for</param>
109 /// <param name="gridserverUrl"></param>
110 /// <param name="gridserverSendkey"></param>
111 /// <param name="gridserverRecvkey"></param>
112 /// <returns>The sim profile. Null if there was a request failure</returns>
113 public RegionProfileData RequestSimProfileData(string regionName, Uri gridserverUrl,
114 string gridserverSendkey, string gridserverRecvkey)
115 {
116 return RequestSimData(gridserverUrl, gridserverSendkey, "region_name_search", regionName);
117 }
118 }
119}
diff --git a/OpenSim/Data/SQLite/Resources/001_AuthStore.sql b/OpenSim/Data/SQLite/Resources/001_AuthStore.sql
new file mode 100644
index 0000000..468567d
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/001_AuthStore.sql
@@ -0,0 +1,18 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE auth (
4 UUID char(36) NOT NULL,
5 passwordHash char(32) NOT NULL default '',
6 passwordSalt char(32) NOT NULL default '',
7 webLoginKey varchar(255) NOT NULL default '',
8 accountType VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
9 PRIMARY KEY (`UUID`)
10);
11
12CREATE TABLE tokens (
13 UUID char(36) NOT NULL,
14 token varchar(255) NOT NULL,
15 validity datetime NOT NULL
16);
17
18COMMIT;
diff --git a/OpenSim/Data/SQLite/Resources/001_Avatar.sql b/OpenSim/Data/SQLite/Resources/001_Avatar.sql
new file mode 100644
index 0000000..7ec906b
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/001_Avatar.sql
@@ -0,0 +1,9 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE Avatars (
4 PrincipalID CHAR(36) NOT NULL,
5 Name VARCHAR(32) NOT NULL,
6 Value VARCHAR(255) NOT NULL DEFAULT '',
7 PRIMARY KEY(PrincipalID, Name));
8
9COMMIT;
diff --git a/OpenSim/Data/SQLite/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLite/Resources/001_FriendsStore.sql
new file mode 100644
index 0000000..f1b9ab9
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/001_FriendsStore.sql
@@ -0,0 +1,10 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE `Friends` (
4 `PrincipalID` CHAR(36) NOT NULL,
5 `Friend` VARCHAR(255) NOT NULL,
6 `Flags` VARCHAR(16) NOT NULL DEFAULT 0,
7 `Offered` VARCHAR(32) NOT NULL DEFAULT 0,
8 PRIMARY KEY(`PrincipalID`, `Friend`));
9
10COMMIT;
diff --git a/OpenSim/Data/SQLite/Resources/001_UserAccount.sql b/OpenSim/Data/SQLite/Resources/001_UserAccount.sql
new file mode 100644
index 0000000..c38d9a7
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/001_UserAccount.sql
@@ -0,0 +1,17 @@
1BEGIN TRANSACTION;
2
3-- useraccounts table
4CREATE TABLE UserAccounts (
5 PrincipalID CHAR(36) primary key,
6 ScopeID CHAR(36) NOT NULL,
7 FirstName VARCHAR(64) NOT NULL,
8 LastName VARCHAR(64) NOT NULL,
9 Email VARCHAR(64),
10 ServiceURLs TEXT,
11 Created INT(11),
12 UserLevel integer NOT NULL DEFAULT 0,
13 UserFlags integer NOT NULL DEFAULT 0,
14 UserTitle varchar(64) NOT NULL DEFAULT ''
15);
16
17COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLite/Resources/002_AuthStore.sql b/OpenSim/Data/SQLite/Resources/002_AuthStore.sql
new file mode 100644
index 0000000..3237b68
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/002_AuthStore.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLite/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLite/Resources/002_FriendsStore.sql
new file mode 100644
index 0000000..6733502
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/002_FriendsStore.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLite/Resources/002_UserAccount.sql b/OpenSim/Data/SQLite/Resources/002_UserAccount.sql
new file mode 100644
index 0000000..c7a6293
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/002_UserAccount.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, surname AS LastName, '' as Email, '' AS ServiceURLs, created as Created FROM users;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs
index c52f60b..a032670 100644
--- a/OpenSim/Data/SQLite/SQLiteAssetData.cs
+++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs
@@ -137,7 +137,7 @@ namespace OpenSim.Data.SQLite
137 cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local)); 137 cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
138 cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary)); 138 cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
139 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); 139 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
140 140
141 cmd.ExecuteNonQuery(); 141 cmd.ExecuteNonQuery();
142 } 142 }
143 } 143 }
@@ -234,7 +234,8 @@ namespace OpenSim.Data.SQLite
234 AssetBase asset = new AssetBase( 234 AssetBase asset = new AssetBase(
235 new UUID((String)row["UUID"]), 235 new UUID((String)row["UUID"]),
236 (String)row["Name"], 236 (String)row["Name"],
237 Convert.ToSByte(row["Type"]) 237 Convert.ToSByte(row["Type"]),
238 UUID.Zero.ToString()
238 ); 239 );
239 240
240 asset.Description = (String) row["Description"]; 241 asset.Description = (String) row["Description"];
diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
new file mode 100644
index 0000000..aa10734
--- /dev/null
+++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
@@ -0,0 +1,262 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.SqliteClient;
35
36namespace OpenSim.Data.SQLite
37{
38 public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData
39 {
40 private string m_Realm;
41 private List<string> m_ColumnNames;
42 private int m_LastExpire;
43 private string m_connectionString;
44
45 protected static SqliteConnection m_Connection;
46 private static bool m_initialized = false;
47
48 public SQLiteAuthenticationData(string connectionString, string realm)
49 : base(connectionString)
50 {
51 m_Realm = realm;
52 m_connectionString = connectionString;
53
54 if (!m_initialized)
55 {
56 m_Connection = new SqliteConnection(connectionString);
57 m_Connection.Open();
58
59 using (SqliteConnection dbcon = (SqliteConnection)((ICloneable)m_Connection).Clone())
60 {
61 dbcon.Open();
62 Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore");
63 m.Update();
64 dbcon.Close();
65 }
66
67 m_initialized = true;
68 }
69 }
70
71 public AuthenticationData Get(UUID principalID)
72 {
73 AuthenticationData ret = new AuthenticationData();
74 ret.Data = new Dictionary<string, object>();
75
76 SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID");
77 cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
78
79 IDataReader result = ExecuteReader(cmd, m_Connection);
80
81 try
82 {
83 if (result.Read())
84 {
85 ret.PrincipalID = principalID;
86
87 if (m_ColumnNames == null)
88 {
89 m_ColumnNames = new List<string>();
90
91 DataTable schemaTable = result.GetSchemaTable();
92 foreach (DataRow row in schemaTable.Rows)
93 m_ColumnNames.Add(row["ColumnName"].ToString());
94 }
95
96 foreach (string s in m_ColumnNames)
97 {
98 if (s == "UUID")
99 continue;
100
101 ret.Data[s] = result[s].ToString();
102 }
103
104 return ret;
105 }
106 else
107 {
108 return null;
109 }
110 }
111 catch
112 {
113 }
114 finally
115 {
116 CloseCommand(cmd);
117 }
118
119 return null;
120 }
121
122 public bool Store(AuthenticationData data)
123 {
124 if (data.Data.ContainsKey("UUID"))
125 data.Data.Remove("UUID");
126
127 string[] fields = new List<string>(data.Data.Keys).ToArray();
128 string[] values = new string[data.Data.Count];
129 int i = 0;
130 foreach (object o in data.Data.Values)
131 values[i++] = o.ToString();
132
133 SqliteCommand cmd = new SqliteCommand();
134
135 if (Get(data.PrincipalID) != null)
136 {
137
138
139 string update = "update `" + m_Realm + "` set ";
140 bool first = true;
141 foreach (string field in fields)
142 {
143 if (!first)
144 update += ", ";
145 update += "`" + field + "` = :" + field;
146 cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
147
148 first = false;
149 }
150
151 update += " where UUID = :UUID";
152 cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
153
154 cmd.CommandText = update;
155 try
156 {
157 if (ExecuteNonQuery(cmd, m_Connection) < 1)
158 {
159 CloseCommand(cmd);
160 return false;
161 }
162 }
163 catch (Exception e)
164 {
165 Console.WriteLine(e.ToString());
166 CloseCommand(cmd);
167 return false;
168 }
169 }
170
171 else
172 {
173 string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
174 String.Join("`, `", fields) +
175 "`) values (:UUID, :" + String.Join(", :", fields) + ")";
176
177 cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
178 foreach (string field in fields)
179 cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
180
181 cmd.CommandText = insert;
182
183 try
184 {
185 if (ExecuteNonQuery(cmd, m_Connection) < 1)
186 {
187 CloseCommand(cmd);
188 return false;
189 }
190 }
191 catch (Exception e)
192 {
193 Console.WriteLine(e.ToString());
194 CloseCommand(cmd);
195 return false;
196 }
197 }
198
199 CloseCommand(cmd);
200
201 return true;
202 }
203
204 public bool SetDataItem(UUID principalID, string item, string value)
205 {
206 SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
207 "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'");
208
209 if (ExecuteNonQuery(cmd, m_Connection) > 0)
210 return true;
211
212 return false;
213 }
214
215 public bool SetToken(UUID principalID, string token, int lifetime)
216 {
217 if (System.Environment.TickCount - m_LastExpire > 30000)
218 DoExpire();
219
220 SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() +
221 "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))");
222
223 if (ExecuteNonQuery(cmd, m_Connection) > 0)
224 {
225 cmd.Dispose();
226 return true;
227 }
228
229 cmd.Dispose();
230 return false;
231 }
232
233 public bool CheckToken(UUID principalID, string token, int lifetime)
234 {
235 if (System.Environment.TickCount - m_LastExpire > 30000)
236 DoExpire();
237
238 SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() +
239 " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')");
240
241 if (ExecuteNonQuery(cmd, m_Connection) > 0)
242 {
243 cmd.Dispose();
244 return true;
245 }
246
247 cmd.Dispose();
248
249 return false;
250 }
251
252 private void DoExpire()
253 {
254 SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')");
255 ExecuteNonQuery(cmd, m_Connection);
256
257 cmd.Dispose();
258
259 m_LastExpire = System.Environment.TickCount;
260 }
261 }
262}
diff --git a/OpenSim/Data/SQLite/SQLiteAvatarData.cs b/OpenSim/Data/SQLite/SQLiteAvatarData.cs
new file mode 100644
index 0000000..b3f4a4c
--- /dev/null
+++ b/OpenSim/Data/SQLite/SQLiteAvatarData.cs
@@ -0,0 +1,74 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using Mono.Data.SqliteClient;
37
38namespace OpenSim.Data.SQLite
39{
40 /// <summary>
41 /// A SQLite Interface for Avatar Data
42 /// </summary>
43 public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>,
44 IAvatarData
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public SQLiteAvatarData(string connectionString, string realm) :
49 base(connectionString, realm, "Avatar")
50 {
51 }
52
53 public bool Delete(UUID principalID, string name)
54 {
55 SqliteCommand cmd = new SqliteCommand();
56
57 cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm);
58 cmd.Parameters.Add(":PrincipalID", principalID.ToString());
59 cmd.Parameters.Add(":Name", name);
60
61 try
62 {
63 if (ExecuteNonQuery(cmd, m_Connection) > 0)
64 return true;
65
66 return false;
67 }
68 finally
69 {
70 CloseCommand(cmd);
71 }
72 }
73 }
74}
diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs
index 1be99ee..bd6b776 100644
--- a/OpenSim/Data/SQLite/SQLiteEstateData.cs
+++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs
@@ -80,11 +80,8 @@ namespace OpenSim.Data.SQLite
80 get { return new List<string>(m_FieldMap.Keys).ToArray(); } 80 get { return new List<string>(m_FieldMap.Keys).ToArray(); }
81 } 81 }
82 82
83 public EstateSettings LoadEstateSettings(UUID regionID) 83 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
84 { 84 {
85 EstateSettings es = new EstateSettings();
86 es.OnSave += StoreEstateSettings;
87
88 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"; 85 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";
89 86
90 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); 87 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
@@ -92,6 +89,14 @@ namespace OpenSim.Data.SQLite
92 cmd.CommandText = sql; 89 cmd.CommandText = sql;
93 cmd.Parameters.Add(":RegionID", regionID.ToString()); 90 cmd.Parameters.Add(":RegionID", regionID.ToString());
94 91
92 return DoLoad(cmd, regionID, create);
93 }
94
95 private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create)
96 {
97 EstateSettings es = new EstateSettings();
98 es.OnSave += StoreEstateSettings;
99
95 IDataReader r = cmd.ExecuteReader(); 100 IDataReader r = cmd.ExecuteReader();
96 101
97 if (r.Read()) 102 if (r.Read())
@@ -120,17 +125,15 @@ namespace OpenSim.Data.SQLite
120 } 125 }
121 r.Close(); 126 r.Close();
122 } 127 }
123 else 128 else if (create)
124 { 129 {
125 // Migration case
126 //
127 r.Close(); 130 r.Close();
128 131
129 List<string> names = new List<string>(FieldList); 132 List<string> names = new List<string>(FieldList);
130 133
131 names.Remove("EstateID"); 134 names.Remove("EstateID");
132 135
133 sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")"; 136 string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
134 137
135 cmd.CommandText = sql; 138 cmd.CommandText = sql;
136 cmd.Parameters.Clear(); 139 cmd.Parameters.Clear();
@@ -176,20 +179,6 @@ namespace OpenSim.Data.SQLite
176 { 179 {
177 } 180 }
178 181
179 // Munge and transfer the ban list
180 //
181 cmd.Parameters.Clear();
182 cmd.CommandText = "insert into estateban select "+es.EstateID.ToString()+", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = :UUID";
183 cmd.Parameters.Add(":UUID", regionID.ToString());
184
185 try
186 {
187 cmd.ExecuteNonQuery();
188 }
189 catch (Exception)
190 {
191 }
192
193 es.Save(); 182 es.Save();
194 } 183 }
195 184
@@ -336,5 +325,63 @@ namespace OpenSim.Data.SQLite
336 325
337 return uuids.ToArray(); 326 return uuids.ToArray();
338 } 327 }
328
329 public EstateSettings LoadEstateSettings(int estateID)
330 {
331 string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID :EstateID";
332
333 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
334
335 cmd.CommandText = sql;
336 cmd.Parameters.Add(":EstateID", estateID.ToString());
337
338 return DoLoad(cmd, UUID.Zero, false);
339 }
340
341 public List<int> GetEstates(string search)
342 {
343 List<int> result = new List<int>();
344
345 string sql = "select EstateID from estate_settings where estate_settings.EstateName :EstateName";
346
347 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
348
349 cmd.CommandText = sql;
350 cmd.Parameters.Add(":EstateName", search);
351
352 IDataReader r = cmd.ExecuteReader();
353
354 while (r.Read())
355 {
356 result.Add(Convert.ToInt32(r["EstateID"]));
357 }
358 r.Close();
359
360 return result;
361 }
362
363 public bool LinkRegion(UUID regionID, int estateID)
364 {
365 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
366
367 cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
368 cmd.Parameters.Add(":RegionID", regionID.ToString());
369 cmd.Parameters.Add(":EstateID", estateID.ToString());
370
371 if (cmd.ExecuteNonQuery() == 0)
372 return false;
373
374 return true;
375 }
376
377 public List<UUID> GetRegions(int estateID)
378 {
379 return new List<UUID>();
380 }
381
382 public bool DeleteEstate(int estateID)
383 {
384 return false;
385 }
339 } 386 }
340} 387}
diff --git a/OpenSim/Data/SQLite/SQLiteFramework.cs b/OpenSim/Data/SQLite/SQLiteFramework.cs
index 12b2750..20b5085 100644
--- a/OpenSim/Data/SQLite/SQLiteFramework.cs
+++ b/OpenSim/Data/SQLite/SQLiteFramework.cs
@@ -40,12 +40,10 @@ namespace OpenSim.Data.SQLite
40 /// </summary> 40 /// </summary>
41 public class SQLiteFramework 41 public class SQLiteFramework
42 { 42 {
43 protected SqliteConnection m_Connection; 43 protected Object m_lockObject = new Object();
44 44
45 protected SQLiteFramework(string connectionString) 45 protected SQLiteFramework(string connectionString)
46 { 46 {
47 m_Connection = new SqliteConnection(connectionString);
48 m_Connection.Open();
49 } 47 }
50 48
51 ////////////////////////////////////////////////////////////// 49 //////////////////////////////////////////////////////////////
@@ -53,27 +51,37 @@ namespace OpenSim.Data.SQLite
53 // All non queries are funneled through one connection 51 // All non queries are funneled through one connection
54 // to increase performance a little 52 // to increase performance a little
55 // 53 //
56 protected int ExecuteNonQuery(SqliteCommand cmd) 54 protected int ExecuteNonQuery(SqliteCommand cmd, SqliteConnection connection)
57 { 55 {
58 lock (m_Connection) 56 lock (connection)
59 { 57 {
60 cmd.Connection = m_Connection; 58 SqliteConnection newConnection =
59 (SqliteConnection)((ICloneable)connection).Clone();
60 newConnection.Open();
61
62 cmd.Connection = newConnection;
63 //Console.WriteLine("XXX " + cmd.CommandText);
61 64
62 return cmd.ExecuteNonQuery(); 65 return cmd.ExecuteNonQuery();
63 } 66 }
64 } 67 }
65 68
66 protected IDataReader ExecuteReader(SqliteCommand cmd) 69 protected IDataReader ExecuteReader(SqliteCommand cmd, SqliteConnection connection)
67 { 70 {
68 SqliteConnection newConnection = 71 lock (connection)
69 (SqliteConnection)((ICloneable)m_Connection).Clone(); 72 {
70 newConnection.Open(); 73 SqliteConnection newConnection =
74 (SqliteConnection)((ICloneable)connection).Clone();
75 newConnection.Open();
71 76
72 cmd.Connection = newConnection; 77 cmd.Connection = newConnection;
73 return cmd.ExecuteReader(); 78 //Console.WriteLine("XXX " + cmd.CommandText);
79
80 return cmd.ExecuteReader();
81 }
74 } 82 }
75 83
76 protected void CloseReaderCommand(SqliteCommand cmd) 84 protected void CloseCommand(SqliteCommand cmd)
77 { 85 {
78 cmd.Connection.Close(); 86 cmd.Connection.Close();
79 cmd.Connection.Dispose(); 87 cmd.Connection.Dispose();
diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs
new file mode 100644
index 0000000..0b12182
--- /dev/null
+++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.SqliteClient;
35
36namespace OpenSim.Data.SQLite
37{
38 public class SQLiteFriendsData : SQLiteGenericTableHandler<FriendsData>, IFriendsData
39 {
40 public SQLiteFriendsData(string connectionString, string realm)
41 : base(connectionString, realm, "FriendsStore")
42 {
43 }
44
45 public FriendsData[] GetFriends(UUID userID)
46 {
47 SqliteCommand cmd = new SqliteCommand();
48
49 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = :PrincipalID", m_Realm);
50 cmd.Parameters.Add(":PrincipalID", userID.ToString());
51
52 return DoQuery(cmd);
53
54 }
55
56 public bool Delete(UUID principalID, string friend)
57 {
58 SqliteCommand cmd = new SqliteCommand();
59
60 cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
61 cmd.Parameters.Add(":PrincipalID", principalID.ToString());
62 cmd.Parameters.Add(":Friend", friend);
63
64 ExecuteNonQuery(cmd, cmd.Connection);
65
66 return true;
67 }
68
69 }
70}
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
index 8e91693..b39bb19 100644
--- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
+++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
@@ -48,16 +48,33 @@ namespace OpenSim.Data.SQLite
48 protected string m_Realm; 48 protected string m_Realm;
49 protected FieldInfo m_DataField = null; 49 protected FieldInfo m_DataField = null;
50 50
51 protected static SqliteConnection m_Connection;
52 private static bool m_initialized;
53
51 public SQLiteGenericTableHandler(string connectionString, 54 public SQLiteGenericTableHandler(string connectionString,
52 string realm, string storeName) : base(connectionString) 55 string realm, string storeName) : base(connectionString)
53 { 56 {
54 m_Realm = realm; 57 m_Realm = realm;
55 if (storeName != String.Empty) 58
59 if (!m_initialized)
56 { 60 {
57 Assembly assem = GetType().Assembly; 61 m_Connection = new SqliteConnection(connectionString);
62 m_Connection.Open();
63
64 if (storeName != String.Empty)
65 {
66 Assembly assem = GetType().Assembly;
67 SqliteConnection newConnection =
68 (SqliteConnection)((ICloneable)m_Connection).Clone();
69 newConnection.Open();
70
71 Migration m = new Migration(newConnection, assem, storeName);
72 m.Update();
73 newConnection.Close();
74 newConnection.Dispose();
75 }
58 76
59 Migration m = new Migration(m_Connection, assem, storeName); 77 m_initialized = true;
60 m.Update();
61 } 78 }
62 79
63 Type t = typeof(T); 80 Type t = typeof(T);
@@ -125,7 +142,7 @@ namespace OpenSim.Data.SQLite
125 142
126 protected T[] DoQuery(SqliteCommand cmd) 143 protected T[] DoQuery(SqliteCommand cmd)
127 { 144 {
128 IDataReader reader = ExecuteReader(cmd); 145 IDataReader reader = ExecuteReader(cmd, m_Connection);
129 if (reader == null) 146 if (reader == null)
130 return new T[0]; 147 return new T[0];
131 148
@@ -180,7 +197,7 @@ namespace OpenSim.Data.SQLite
180 result.Add(row); 197 result.Add(row);
181 } 198 }
182 199
183 CloseReaderCommand(cmd); 200 CloseCommand(cmd);
184 201
185 return result.ToArray(); 202 return result.ToArray();
186 } 203 }
@@ -229,7 +246,7 @@ namespace OpenSim.Data.SQLite
229 246
230 cmd.CommandText = query; 247 cmd.CommandText = query;
231 248
232 if (ExecuteNonQuery(cmd) > 0) 249 if (ExecuteNonQuery(cmd, m_Connection) > 0)
233 return true; 250 return true;
234 251
235 return false; 252 return false;
@@ -242,7 +259,7 @@ namespace OpenSim.Data.SQLite
242 cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field); 259 cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field);
243 cmd.Parameters.Add(new SqliteParameter(field, val)); 260 cmd.Parameters.Add(new SqliteParameter(field, val));
244 261
245 if (ExecuteNonQuery(cmd) > 0) 262 if (ExecuteNonQuery(cmd, m_Connection) > 0)
246 return true; 263 return true;
247 264
248 return false; 265 return false;
diff --git a/OpenSim/Data/SQLite/SQLiteGridData.cs b/OpenSim/Data/SQLite/SQLiteGridData.cs
deleted file mode 100644
index 18abb88..0000000
--- a/OpenSim/Data/SQLite/SQLiteGridData.cs
+++ /dev/null
@@ -1,286 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using OpenMetaverse;
34using OpenSim.Framework;
35
36namespace OpenSim.Data.SQLite
37{
38 /// <summary>
39 /// A Grid Interface to the SQLite database
40 /// </summary>
41 public class SQLiteGridData : GridDataBase
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 /// <summary>
46 /// SQLite database manager
47 /// </summary>
48 private SQLiteManager database;
49
50 override public void Initialise()
51 {
52 m_log.Info("[SQLite]: " + Name + " cannot be default-initialized!");
53 throw new PluginNotInitialisedException (Name);
54 }
55
56 /// <summary>
57 /// <list type="bullet">
58 /// <item>Initialises Inventory interface</item>
59 /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
60 /// <item>use default URI if connect string is empty.</item>
61 /// </list>
62 /// </summary>
63 /// <param name="dbconnect">connect string</param>
64 override public void Initialise(string connect)
65 {
66 database = new SQLiteManager(connect);
67 }
68
69 /// <summary>
70 /// Shuts down the grid interface
71 /// </summary>
72 override public void Dispose()
73 {
74 database.Close();
75 }
76
77 /// <summary>
78 /// Returns the name of this grid interface
79 /// </summary>
80 /// <returns>A string containing the grid interface</returns>
81 override public string Name
82 {
83 get { return "SQLite OpenGridData"; }
84 }
85
86 /// <summary>
87 /// Returns the version of this grid interface
88 /// </summary>
89 /// <returns>A string containing the version</returns>
90 override public string Version
91 {
92 get { return "0.1"; }
93 }
94
95 /// <summary>
96 /// Returns a list of regions within the specified ranges
97 /// </summary>
98 /// <param name="a">minimum X coordinate</param>
99 /// <param name="b">minimum Y coordinate</param>
100 /// <param name="c">maximum X coordinate</param>
101 /// <param name="d">maximum Y coordinate</param>
102 /// <returns>An array of region profiles</returns>
103 /// <remarks>NOT IMPLEMENTED ? always return null</remarks>
104 override public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d)
105 {
106 return null;
107 }
108
109
110 /// <summary>
111 /// Returns up to maxNum profiles of regions that have a name starting with namePrefix
112 /// </summary>
113 /// <param name="name">The name to match against</param>
114 /// <param name="maxNum">Maximum number of profiles to return</param>
115 /// <returns>A list of sim profiles</returns>
116 override public List<RegionProfileData> GetRegionsByName (string namePrefix, uint maxNum)
117 {
118 return null;
119 }
120
121 /// <summary>
122 /// Returns a sim profile from it's handle
123 /// </summary>
124 /// <param name="handle">Region location handle</param>
125 /// <returns>Sim profile</returns>
126 override public RegionProfileData GetProfileByHandle(ulong handle)
127 {
128 Dictionary<string, string> param = new Dictionary<string, string>();
129 param["handle"] = handle.ToString();
130
131 IDbCommand result = database.Query("SELECT * FROM regions WHERE handle = @handle", param);
132 IDataReader reader = result.ExecuteReader();
133
134 RegionProfileData row = database.getRow(reader);
135 reader.Close();
136 result.Dispose();
137
138 return row;
139 }
140
141 /// <summary>
142 /// Returns a sim profile from it's Region name string
143 /// </summary>
144 /// <param name="regionName">The region name search query</param>
145 /// <returns>The sim profile</returns>
146 override public RegionProfileData GetProfileByString(string regionName)
147 {
148 if (regionName.Length > 2)
149 {
150 Dictionary<string, string> param = new Dictionary<string, string>();
151 // Add % because this is a like query.
152 param["?regionName"] = regionName + "%";
153 // Only returns one record or no record.
154 IDbCommand result = database.Query("SELECT * FROM regions WHERE regionName like ?regionName LIMIT 1", param);
155 IDataReader reader = result.ExecuteReader();
156
157 RegionProfileData row = database.getRow(reader);
158 reader.Close();
159 result.Dispose();
160
161 return row;
162 }
163 else
164 {
165 //m_log.Error("[DATABASE]: Searched for a Region Name shorter then 3 characters");
166 return null;
167 }
168 }
169
170 /// <summary>
171 /// Returns a sim profile from it's UUID
172 /// </summary>
173 /// <param name="uuid">The region UUID</param>
174 /// <returns>The sim profile</returns>
175 override public RegionProfileData GetProfileByUUID(UUID uuid)
176 {
177 Dictionary<string, string> param = new Dictionary<string, string>();
178 param["uuid"] = uuid.ToString();
179
180 IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = @uuid", param);
181 IDataReader reader = result.ExecuteReader();
182
183 RegionProfileData row = database.getRow(reader);
184 reader.Close();
185 result.Dispose();
186
187 return row;
188 }
189
190 /// <summary>
191 /// Returns a list of avatar and UUIDs that match the query
192 /// </summary>
193 /// <remarks>do nothing yet</remarks>
194 public List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query)
195 {
196 //Do nothing yet
197 List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
198 return returnlist;
199 }
200
201 /// <summary>
202 /// Adds a new specified region to the database
203 /// </summary>
204 /// <param name="profile">The profile to add</param>
205 /// <returns>A dataresponse enum indicating success</returns>
206 override public DataResponse StoreProfile(RegionProfileData profile)
207 {
208 if (database.insertRow(profile))
209 {
210 return DataResponse.RESPONSE_OK;
211 }
212 else
213 {
214 return DataResponse.RESPONSE_ERROR;
215 }
216 }
217
218 /// <summary>
219 /// Deletes a sim profile from the database
220 /// </summary>
221 /// <param name="uuid">the sim UUID</param>
222 /// <returns>Successful?</returns>
223 override public DataResponse DeleteProfile(string uuid)
224 {
225 Dictionary<string, string> param = new Dictionary<string, string>();
226 param["uuid"] = uuid;
227
228 IDbCommand result = database.Query("DELETE FROM regions WHERE uuid = @uuid", param);
229 if (result.ExecuteNonQuery() > 0)
230 {
231 return DataResponse.RESPONSE_OK;
232 }
233 return DataResponse.RESPONSE_ERROR;
234 }
235
236 /// <summary>
237 /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret.
238 /// </summary>
239 /// <param name="uuid">The UUID of the challenger</param>
240 /// <param name="handle">The attempted regionHandle of the challenger</param>
241 /// <param name="authkey">The secret</param>
242 /// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
243 override public bool AuthenticateSim(UUID uuid, ulong handle, string authkey)
244 {
245 bool throwHissyFit = false; // Should be true by 1.0
246
247 if (throwHissyFit)
248 throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
249
250 RegionProfileData data = GetProfileByUUID(uuid);
251
252 return (handle == data.regionHandle && authkey == data.regionSecret);
253 }
254
255 /// <summary>
256 /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
257 /// </summary>
258 /// <remarks>This requires a security audit.</remarks>
259 /// <param name="uuid"></param>
260 /// <param name="handle"></param>
261 /// <param name="authhash"></param>
262 /// <param name="challenge"></param>
263 /// <returns></returns>
264 public bool AuthenticateSim(UUID uuid, ulong handle, string authhash, string challenge)
265 {
266 // SHA512Managed HashProvider = new SHA512Managed();
267 // Encoding TextProvider = new UTF8Encoding();
268
269 // byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
270 // byte[] hash = HashProvider.ComputeHash(stream);
271
272 return false;
273 }
274
275 /// <summary>
276 /// NOT IMPLEMENTED
277 /// </summary>
278 /// <param name="x">x coordinate</param>
279 /// <param name="y">y coordinate</param>
280 /// <returns>always return null</returns>
281 override public ReservationData GetReservationAtPoint(uint x, uint y)
282 {
283 return null;
284 }
285 }
286}
diff --git a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs
index 64591fd..a5e0517 100644
--- a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs
+++ b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs
@@ -46,10 +46,12 @@ namespace OpenSim.Data.SQLite
46 private const string invItemsSelect = "select * from inventoryitems"; 46 private const string invItemsSelect = "select * from inventoryitems";
47 private const string invFoldersSelect = "select * from inventoryfolders"; 47 private const string invFoldersSelect = "select * from inventoryfolders";
48 48
49 private SqliteConnection conn; 49 private static SqliteConnection conn;
50 private DataSet ds; 50 private static DataSet ds;
51 private SqliteDataAdapter invItemsDa; 51 private static SqliteDataAdapter invItemsDa;
52 private SqliteDataAdapter invFoldersDa; 52 private static SqliteDataAdapter invFoldersDa;
53
54 private static bool m_Initialized = false;
53 55
54 public void Initialise() 56 public void Initialise()
55 { 57 {
@@ -67,39 +69,44 @@ namespace OpenSim.Data.SQLite
67 /// <param name="dbconnect">connect string</param> 69 /// <param name="dbconnect">connect string</param>
68 public void Initialise(string dbconnect) 70 public void Initialise(string dbconnect)
69 { 71 {
70 if (dbconnect == string.Empty) 72 if (!m_Initialized)
71 { 73 {
72 dbconnect = "URI=file:inventoryStore.db,version=3"; 74 m_Initialized = true;
73 } 75
74 m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect); 76 if (dbconnect == string.Empty)
75 conn = new SqliteConnection(dbconnect); 77 {
78 dbconnect = "URI=file:inventoryStore.db,version=3";
79 }
80 m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect);
81 conn = new SqliteConnection(dbconnect);
76 82
77 conn.Open(); 83 conn.Open();
78 84
79 Assembly assem = GetType().Assembly; 85 Assembly assem = GetType().Assembly;
80 Migration m = new Migration(conn, assem, "InventoryStore"); 86 Migration m = new Migration(conn, assem, "InventoryStore");
81 m.Update(); 87 m.Update();
82 88
83 SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); 89 SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn);
84 invItemsDa = new SqliteDataAdapter(itemsSelectCmd); 90 invItemsDa = new SqliteDataAdapter(itemsSelectCmd);
85 // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); 91 // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa);
86 92
87 SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); 93 SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn);
88 invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); 94 invFoldersDa = new SqliteDataAdapter(foldersSelectCmd);
89 95
90 ds = new DataSet(); 96 ds = new DataSet();
91 97
92 ds.Tables.Add(createInventoryFoldersTable()); 98 ds.Tables.Add(createInventoryFoldersTable());
93 invFoldersDa.Fill(ds.Tables["inventoryfolders"]); 99 invFoldersDa.Fill(ds.Tables["inventoryfolders"]);
94 setupFoldersCommands(invFoldersDa, conn); 100 setupFoldersCommands(invFoldersDa, conn);
95 m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); 101 m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions");
96 102
97 ds.Tables.Add(createInventoryItemsTable()); 103 ds.Tables.Add(createInventoryItemsTable());
98 invItemsDa.Fill(ds.Tables["inventoryitems"]); 104 invItemsDa.Fill(ds.Tables["inventoryitems"]);
99 setupItemsCommands(invItemsDa, conn); 105 setupItemsCommands(invItemsDa, conn);
100 m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); 106 m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions");
101 107
102 ds.AcceptChanges(); 108 ds.AcceptChanges();
109 }
103 } 110 }
104 111
105 /// <summary> 112 /// <summary>
diff --git a/OpenSim/Data/SQLite/SQLiteManager.cs b/OpenSim/Data/SQLite/SQLiteManager.cs
deleted file mode 100644
index b6d4a1c..0000000
--- a/OpenSim/Data/SQLite/SQLiteManager.cs
+++ /dev/null
@@ -1,225 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Data.SQLite;
32using System.Reflection;
33using log4net;
34using OpenMetaverse;
35
36namespace OpenSim.Data.SQLite
37{
38 /// <summary>
39 /// SQLite Manager
40 /// </summary>
41 internal class SQLiteManager : SQLiteUtil
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 private IDbConnection dbcon;
46
47 /// <summary>
48 /// <list type="bullet">
49 /// <item>Initialises and creates a new SQLite connection and maintains it.</item>
50 /// <item>use default URI if connect string is empty.</item>
51 /// </list>
52 /// </summary>
53 /// <param name="connect">connect string</param>
54 public SQLiteManager(string connect)
55 {
56 try
57 {
58 string connectionString = String.Empty;
59 if (connect != String.Empty)
60 {
61 connectionString = connect;
62 }
63 else
64 {
65 m_log.Warn("[SQLITE] grid db not specified, using default");
66 connectionString = "URI=file:GridServerSqlite.db;";
67 }
68
69 dbcon = new SQLiteConnection(connectionString);
70
71 dbcon.Open();
72 }
73 catch (Exception e)
74 {
75 throw new Exception("Error initialising SQLite Database: " + e.ToString());
76 }
77 }
78
79 /// <summary>
80 /// Shuts down the database connection
81 /// </summary>
82 public void Close()
83 {
84 dbcon.Close();
85 dbcon = null;
86 }
87
88 /// <summary>
89 /// Runs a query with protection against SQL Injection by using parameterised input.
90 /// </summary>
91 /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
92 /// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
93 /// <returns>A SQLite DB Command</returns>
94 public IDbCommand Query(string sql, Dictionary<string, string> parameters)
95 {
96 SQLiteCommand dbcommand = (SQLiteCommand) dbcon.CreateCommand();
97 dbcommand.CommandText = sql;
98 foreach (KeyValuePair<string, string> param in parameters)
99 {
100 SQLiteParameter paramx = new SQLiteParameter(param.Key, param.Value);
101 dbcommand.Parameters.Add(paramx);
102 }
103
104 return (IDbCommand) dbcommand;
105 }
106
107 /// <summary>
108 /// Reads a region row from a database reader
109 /// </summary>
110 /// <param name="reader">An active database reader</param>
111 /// <returns>A region profile</returns>
112 public RegionProfileData getRow(IDataReader reader)
113 {
114 RegionProfileData retval = new RegionProfileData();
115
116 if (reader.Read())
117 {
118 // Region Main
119 retval.regionHandle = (ulong) reader["regionHandle"];
120 retval.regionName = (string) reader["regionName"];
121 retval.UUID = new UUID((string) reader["uuid"]);
122
123 // Secrets
124 retval.regionRecvKey = (string) reader["regionRecvKey"];
125 retval.regionSecret = (string) reader["regionSecret"];
126 retval.regionSendKey = (string) reader["regionSendKey"];
127
128 // Region Server
129 retval.regionDataURI = (string) reader["regionDataURI"];
130 retval.regionOnline = false; // Needs to be pinged before this can be set.
131 retval.serverIP = (string) reader["serverIP"];
132 retval.serverPort = (uint) reader["serverPort"];
133 retval.serverURI = (string) reader["serverURI"];
134
135 // Location
136 retval.regionLocX = (uint) ((int) reader["locX"]);
137 retval.regionLocY = (uint) ((int) reader["locY"]);
138 retval.regionLocZ = (uint) ((int) reader["locZ"]);
139
140 // Neighbours - 0 = No Override
141 retval.regionEastOverrideHandle = (ulong) reader["eastOverrideHandle"];
142 retval.regionWestOverrideHandle = (ulong) reader["westOverrideHandle"];
143 retval.regionSouthOverrideHandle = (ulong) reader["southOverrideHandle"];
144 retval.regionNorthOverrideHandle = (ulong) reader["northOverrideHandle"];
145
146 // Assets
147 retval.regionAssetURI = (string) reader["regionAssetURI"];
148 retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"];
149 retval.regionAssetSendKey = (string) reader["regionAssetSendKey"];
150
151 // Userserver
152 retval.regionUserURI = (string) reader["regionUserURI"];
153 retval.regionUserRecvKey = (string) reader["regionUserRecvKey"];
154 retval.regionUserSendKey = (string) reader["regionUserSendKey"];
155 }
156 else
157 {
158 throw new Exception("No rows to return");
159 }
160 return retval;
161 }
162
163 /// <summary>
164 /// Inserts a new region into the database
165 /// </summary>
166 /// <param name="profile">The region to insert</param>
167 /// <returns>Success?</returns>
168 public bool insertRow(RegionProfileData profile)
169 {
170 string sql =
171 "REPLACE INTO regions VALUES (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, ";
172 sql +=
173 "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, ";
174 sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey) VALUES ";
175
176 sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, ";
177 sql +=
178 "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, ";
179 sql += "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey);";
180
181 Dictionary<string, string> parameters = new Dictionary<string, string>();
182
183 parameters["regionHandle"] = profile.regionHandle.ToString();
184 parameters["regionName"] = profile.regionName;
185 parameters["uuid"] = profile.UUID.ToString();
186 parameters["regionRecvKey"] = profile.regionRecvKey;
187 parameters["regionSendKey"] = profile.regionSendKey;
188 parameters["regionDataURI"] = profile.regionDataURI;
189 parameters["serverIP"] = profile.serverIP;
190 parameters["serverPort"] = profile.serverPort.ToString();
191 parameters["serverURI"] = profile.serverURI;
192 parameters["locX"] = profile.regionLocX.ToString();
193 parameters["locY"] = profile.regionLocY.ToString();
194 parameters["locZ"] = profile.regionLocZ.ToString();
195 parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString();
196 parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString();
197 parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString();
198 parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString();
199 parameters["regionAssetURI"] = profile.regionAssetURI;
200 parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey;
201 parameters["regionAssetSendKey"] = profile.regionAssetSendKey;
202 parameters["regionUserURI"] = profile.regionUserURI;
203 parameters["regionUserRecvKey"] = profile.regionUserRecvKey;
204 parameters["regionUserSendKey"] = profile.regionUserSendKey;
205
206 bool returnval = false;
207
208 try
209 {
210 IDbCommand result = Query(sql, parameters);
211
212 if (result.ExecuteNonQuery() == 1)
213 returnval = true;
214
215 result.Dispose();
216 }
217 catch (Exception)
218 {
219 return false;
220 }
221
222 return returnval;
223 }
224 }
225}
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 81c0703..d2ba9ae 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -272,13 +272,13 @@ namespace OpenSim.Data.SQLite
272 Commit(); 272 Commit();
273 } 273 }
274 } 274 }
275 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) 275 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
276 { 276 {
277 //This connector doesn't support the windlight module yet 277 //This connector doesn't support the windlight module yet
278 //Return default LL windlight settings 278 //Return default LL windlight settings
279 return new RegionMeta7WindlightData(); 279 return new RegionLightShareData();
280 } 280 }
281 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) 281 public void StoreRegionWindlightSettings(RegionLightShareData wl)
282 { 282 {
283 //This connector doesn't support the windlight module yet 283 //This connector doesn't support the windlight module yet
284 } 284 }
diff --git a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs
new file mode 100644
index 0000000..67cf716
--- /dev/null
+++ b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.SqliteClient;
35
36namespace OpenSim.Data.SQLite
37{
38 public class SQLiteUserAccountData : SQLiteGenericTableHandler<UserAccountData>, IUserAccountData
39 {
40 public SQLiteUserAccountData(string connectionString, string realm)
41 : base(connectionString, realm, "UserAccount")
42 {
43 }
44
45 public UserAccountData[] GetUsers(UUID scopeID, string query)
46 {
47 string[] words = query.Split(new char[] {' '});
48
49 for (int i = 0 ; i < words.Length ; i++)
50 {
51 if (words[i].Length < 3)
52 {
53 if (i != words.Length - 1)
54 Array.Copy(words, i + 1, words, i, words.Length - i - 1);
55 Array.Resize(ref words, words.Length - 1);
56 }
57 }
58
59 if (words.Length == 0)
60 return new UserAccountData[0];
61
62 if (words.Length > 2)
63 return new UserAccountData[0];
64
65 SqliteCommand cmd = new SqliteCommand();
66
67 if (words.Length == 1)
68 {
69 cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')",
70 m_Realm, scopeID.ToString(), words[0]);
71 }
72 else
73 {
74 cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')",
75 m_Realm, scopeID.ToString(), words[0], words[1]);
76 }
77
78 return DoQuery(cmd);
79 }
80 }
81}
diff --git a/OpenSim/Data/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs
deleted file mode 100644
index caddcf8..0000000
--- a/OpenSim/Data/SQLite/SQLiteUserData.cs
+++ /dev/null
@@ -1,1262 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using Mono.Data.SqliteClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37namespace OpenSim.Data.SQLite
38{
39 /// <summary>
40 /// A User storage interface for the SQLite database system
41 /// </summary>
42 public class SQLiteUserData : UserDataBase
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 /// <summary>
47 /// The database manager
48 /// </summary>
49 /// <summary>
50 /// Artificial constructor called upon plugin load
51 /// </summary>
52 private const string SelectUserByUUID = "select * from users where UUID=:UUID";
53 private const string SelectUserByName = "select * from users where username=:username and surname=:surname";
54 private const string SelectFriendsByUUID = "select a.friendID, a.friendPerms, b.friendPerms from userfriends as a, userfriends as b where a.ownerID=:ownerID and b.ownerID=a.friendID and b.friendID=a.ownerID";
55
56 private const string userSelect = "select * from users";
57 private const string userFriendsSelect = "select a.ownerID as ownerID,a.friendID as friendID,a.friendPerms as friendPerms,b.friendPerms as ownerperms, b.ownerID as fownerID, b.friendID as ffriendID from userfriends as a, userfriends as b";
58 private const string userAgentSelect = "select * from useragents";
59 private const string AvatarAppearanceSelect = "select * from avatarappearance";
60
61 private const string AvatarPickerAndSQL = "select * from users where username like :username and surname like :surname";
62 private const string AvatarPickerOrSQL = "select * from users where username like :username or surname like :surname";
63
64 private DataSet ds;
65 private SqliteDataAdapter da;
66 private SqliteDataAdapter daf;
67 private SqliteDataAdapter dua;
68 private SqliteDataAdapter daa;
69 SqliteConnection g_conn;
70
71 public override void Initialise()
72 {
73 m_log.Info("[SQLiteUserData]: " + Name + " cannot be default-initialized!");
74 throw new PluginNotInitialisedException (Name);
75 }
76
77 /// <summary>
78 /// <list type="bullet">
79 /// <item>Initialises User Interface</item>
80 /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
81 /// <item>use default URI if connect string string is empty.</item>
82 /// </list>
83 /// </summary>
84 /// <param name="connect">connect string</param>
85 override public void Initialise(string connect)
86 {
87 // default to something sensible
88 if (connect == "")
89 connect = "URI=file:userprofiles.db,version=3";
90
91 SqliteConnection conn = new SqliteConnection(connect);
92
93 // This sucks, but It doesn't seem to work with the dataset Syncing :P
94 g_conn = conn;
95 g_conn.Open();
96
97 Assembly assem = GetType().Assembly;
98 Migration m = new Migration(g_conn, assem, "UserStore");
99 m.Update();
100
101
102 ds = new DataSet();
103 da = new SqliteDataAdapter(new SqliteCommand(userSelect, conn));
104 dua = new SqliteDataAdapter(new SqliteCommand(userAgentSelect, conn));
105 daf = new SqliteDataAdapter(new SqliteCommand(userFriendsSelect, conn));
106 daa = new SqliteDataAdapter(new SqliteCommand(AvatarAppearanceSelect, conn));
107 //if (daa == null) m_log.Info("[SQLiteUserData]: daa = null");
108
109 lock (ds)
110 {
111 ds.Tables.Add(createUsersTable());
112 ds.Tables.Add(createUserAgentsTable());
113 ds.Tables.Add(createUserFriendsTable());
114 ds.Tables.Add(createAvatarAppearanceTable());
115
116 setupUserCommands(da, conn);
117 da.Fill(ds.Tables["users"]);
118
119 setupAgentCommands(dua, conn);
120 dua.Fill(ds.Tables["useragents"]);
121
122 setupUserFriendsCommands(daf, conn);
123 daf.Fill(ds.Tables["userfriends"]);
124
125 setupAvatarAppearanceCommands(daa, conn);
126 daa.Fill(ds.Tables["avatarappearance"]);
127 }
128
129 return;
130 }
131
132 public override void Dispose ()
133 {
134 if (g_conn != null)
135 {
136 g_conn.Close();
137 g_conn = null;
138 }
139 if (ds != null)
140 {
141 ds.Dispose();
142 ds = null;
143 }
144 if (da != null)
145 {
146 da.Dispose();
147 da = null;
148 }
149 if (daf != null)
150 {
151 daf.Dispose();
152 daf = null;
153 }
154 if (dua != null)
155 {
156 dua.Dispose();
157 dua = null;
158 }
159 if (daa != null)
160 {
161 daa.Dispose();
162 daa = null;
163 }
164 }
165
166 /// <summary>
167 /// see IUserDataPlugin,
168 /// Get user data profile by UUID
169 /// </summary>
170 /// <param name="uuid">User UUID</param>
171 /// <returns>user profile data</returns>
172 override public UserProfileData GetUserByUUID(UUID uuid)
173 {
174 lock (ds)
175 {
176 DataRow row = ds.Tables["users"].Rows.Find(uuid.ToString());
177 if (row != null)
178 {
179 UserProfileData user = buildUserProfile(row);
180 return user;
181 }
182 else
183 {
184 return null;
185 }
186 }
187 }
188
189 /// <summary>
190 /// see IUserDataPlugin,
191 /// Get user data profile by name
192 /// </summary>
193 /// <param name="fname">first name</param>
194 /// <param name="lname">last name</param>
195 /// <returns>user profile data</returns>
196 override public UserProfileData GetUserByName(string fname, string lname)
197 {
198 string select = "surname = '" + lname + "' and username = '" + fname + "'";
199 lock (ds)
200 {
201 DataRow[] rows = ds.Tables["users"].Select(select);
202 if (rows.Length > 0)
203 {
204 UserProfileData user = buildUserProfile(rows[0]);
205 return user;
206 }
207 else
208 {
209 return null;
210 }
211 }
212 }
213
214 #region User Friends List Data
215
216 private bool ExistsFriend(UUID owner, UUID friend)
217 {
218 string FindFriends = "select * from userfriends where (ownerID=:ownerID and friendID=:friendID) or (ownerID=:friendID and friendID=:ownerID)";
219 using (SqliteCommand cmd = new SqliteCommand(FindFriends, g_conn))
220 {
221 cmd.Parameters.Add(new SqliteParameter(":ownerID", owner.ToString()));
222 cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString()));
223 try
224 {
225 using (IDataReader reader = cmd.ExecuteReader())
226 {
227 if (reader.Read())
228 {
229 reader.Close();
230 return true;
231 }
232 else
233 {
234 reader.Close();
235 return false;
236 }
237 }
238 }
239 catch (Exception ex)
240 {
241 m_log.Error("[USER DB]: Exception getting friends list for user: " + ex.ToString());
242 return false;
243 }
244 }
245 }
246 /// <summary>
247 /// Add a new friend in the friendlist
248 /// </summary>
249 /// <param name="friendlistowner">UUID of the friendlist owner</param>
250 /// <param name="friend">UUID of the friend to add</param>
251 /// <param name="perms">permission flag</param>
252 override public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
253 {
254 if (ExistsFriend(friendlistowner, friend))
255 return;
256
257 string InsertFriends = "insert into userfriends(ownerID, friendID, friendPerms) values(:ownerID, :friendID, :perms)";
258 using (SqliteCommand cmd = new SqliteCommand(InsertFriends, g_conn))
259 {
260 cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString()));
261 cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString()));
262 cmd.Parameters.Add(new SqliteParameter(":perms", perms));
263 cmd.ExecuteNonQuery();
264 }
265 using (SqliteCommand cmd = new SqliteCommand(InsertFriends, g_conn))
266 {
267 cmd.Parameters.Add(new SqliteParameter(":ownerID", friend.ToString()));
268 cmd.Parameters.Add(new SqliteParameter(":friendID", friendlistowner.ToString()));
269 cmd.Parameters.Add(new SqliteParameter(":perms", perms));
270 cmd.ExecuteNonQuery();
271 }
272 }
273
274 /// <summary>
275 /// Remove a user from the friendlist
276 /// </summary>
277 /// <param name="friendlistowner">UUID of the friendlist owner</param>
278 /// <param name="friend">UUID of the friend to remove</param>
279 override public void RemoveUserFriend(UUID friendlistowner, UUID friend)
280 {
281 string DeletePerms = "delete from userfriends where (ownerID=:ownerID and friendID=:friendID) or (ownerID=:friendID and friendID=:ownerID)";
282 using (SqliteCommand cmd = new SqliteCommand(DeletePerms, g_conn))
283 {
284 cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString()));
285 cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString()));
286 cmd.ExecuteNonQuery();
287 }
288 }
289
290 /// <summary>
291 /// Update the friendlist permission
292 /// </summary>
293 /// <param name="friendlistowner">UUID of the friendlist owner</param>
294 /// <param name="friend">UUID of the friend to modify</param>
295 /// <param name="perms">updated permission flag</param>
296 override public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
297 {
298 string UpdatePerms = "update userfriends set friendPerms=:perms where ownerID=:ownerID and friendID=:friendID";
299 using (SqliteCommand cmd = new SqliteCommand(UpdatePerms, g_conn))
300 {
301 cmd.Parameters.Add(new SqliteParameter(":perms", perms));
302 cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString()));
303 cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString()));
304 cmd.ExecuteNonQuery();
305 }
306 }
307
308 /// <summary>
309 /// Get (fetch?) the friendlist for a user
310 /// </summary>
311 /// <param name="friendlistowner">UUID of the friendlist owner</param>
312 /// <returns>The friendlist list</returns>
313 override public List<FriendListItem> GetUserFriendList(UUID friendlistowner)
314 {
315 List<FriendListItem> returnlist = new List<FriendListItem>();
316
317 using (SqliteCommand cmd = new SqliteCommand(SelectFriendsByUUID, g_conn))
318 {
319 cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString()));
320
321 try
322 {
323 using (IDataReader reader = cmd.ExecuteReader())
324 {
325 while (reader.Read())
326 {
327 FriendListItem user = new FriendListItem();
328 user.FriendListOwner = friendlistowner;
329 user.Friend = new UUID((string)reader[0]);
330 user.FriendPerms = Convert.ToUInt32(reader[1]);
331 user.FriendListOwnerPerms = Convert.ToUInt32(reader[2]);
332 returnlist.Add(user);
333 }
334 reader.Close();
335 }
336 }
337 catch (Exception ex)
338 {
339 m_log.Error("[USER DB]: Exception getting friends list for user: " + ex.ToString());
340 }
341 }
342
343 return returnlist;
344 }
345
346 override public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids)
347 {
348 Dictionary<UUID, FriendRegionInfo> infos = new Dictionary<UUID,FriendRegionInfo>();
349
350 DataTable agents = ds.Tables["useragents"];
351 foreach (UUID uuid in uuids)
352 {
353 lock (ds)
354 {
355 DataRow row = agents.Rows.Find(uuid.ToString());
356 if (row == null) infos[uuid] = null;
357 else
358 {
359 FriendRegionInfo fri = new FriendRegionInfo();
360 fri.isOnline = (bool)row["agentOnline"];
361 fri.regionHandle = Convert.ToUInt64(row["currentHandle"]);
362 infos[uuid] = fri;
363 }
364 }
365 }
366 return infos;
367 }
368
369 #endregion
370
371 /// <summary>
372 ///
373 /// </summary>
374 /// <param name="queryID"></param>
375 /// <param name="query"></param>
376 /// <returns></returns>
377 override public List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query)
378 {
379 List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
380 string[] querysplit;
381 querysplit = query.Split(' ');
382 if (querysplit.Length == 2)
383 {
384 using (SqliteCommand cmd = new SqliteCommand(AvatarPickerAndSQL, g_conn))
385 {
386 cmd.Parameters.Add(new SqliteParameter(":username", querysplit[0] + "%"));
387 cmd.Parameters.Add(new SqliteParameter(":surname", querysplit[1] + "%"));
388
389 using (IDataReader reader = cmd.ExecuteReader())
390 {
391 while (reader.Read())
392 {
393 AvatarPickerAvatar user = new AvatarPickerAvatar();
394 user.AvatarID = new UUID((string) reader["UUID"]);
395 user.firstName = (string) reader["username"];
396 user.lastName = (string) reader["surname"];
397 returnlist.Add(user);
398 }
399 reader.Close();
400 }
401 }
402 }
403 else if (querysplit.Length == 1)
404 {
405 using (SqliteCommand cmd = new SqliteCommand(AvatarPickerOrSQL, g_conn))
406 {
407 cmd.Parameters.Add(new SqliteParameter(":username", querysplit[0] + "%"));
408 cmd.Parameters.Add(new SqliteParameter(":surname", querysplit[0] + "%"));
409
410 using (IDataReader reader = cmd.ExecuteReader())
411 {
412 while (reader.Read())
413 {
414 AvatarPickerAvatar user = new AvatarPickerAvatar();
415 user.AvatarID = new UUID((string) reader["UUID"]);
416 user.firstName = (string) reader["username"];
417 user.lastName = (string) reader["surname"];
418 returnlist.Add(user);
419 }
420 reader.Close();
421 }
422 }
423 }
424 return returnlist;
425 }
426
427 /// <summary>
428 /// Returns a user by UUID direct
429 /// </summary>
430 /// <param name="uuid">The user's account ID</param>
431 /// <returns>A matching user profile</returns>
432 override public UserAgentData GetAgentByUUID(UUID uuid)
433 {
434 lock (ds)
435 {
436 DataRow row = ds.Tables["useragents"].Rows.Find(uuid.ToString());
437 if (row != null)
438 {
439 return buildUserAgent(row);
440 }
441 else
442 {
443 return null;
444 }
445 }
446 }
447
448 /// <summary>
449 /// Returns a session by account name
450 /// </summary>
451 /// <param name="name">The account name</param>
452 /// <returns>The user's session agent</returns>
453 override public UserAgentData GetAgentByName(string name)
454 {
455 return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
456 }
457
458 /// <summary>
459 /// Returns a session by account name
460 /// </summary>
461 /// <param name="fname">The first part of the user's account name</param>
462 /// <param name="lname">The second part of the user's account name</param>
463 /// <returns>A user agent</returns>
464 override public UserAgentData GetAgentByName(string fname, string lname)
465 {
466 UserAgentData agent = null;
467
468 UserProfileData profile = GetUserByName(fname, lname);
469 if (profile != null)
470 {
471 agent = GetAgentByUUID(profile.ID);
472 }
473 return agent;
474 }
475
476 /// <summary>
477 /// DEPRECATED? Store the weblogin key
478 /// </summary>
479 /// <param name="AgentID">UUID of the user</param>
480 /// <param name="WebLoginKey">UUID of the weblogin</param>
481 override public void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey)
482 {
483 DataTable users = ds.Tables["users"];
484 lock (ds)
485 {
486 DataRow row = users.Rows.Find(AgentID.ToString());
487 if (row == null)
488 {
489 m_log.Warn("[USER DB]: Unable to store new web login key for non-existant user");
490 }
491 else
492 {
493 UserProfileData user = GetUserByUUID(AgentID);
494 user.WebLoginKey = WebLoginKey;
495 fillUserRow(row, user);
496 da.Update(ds, "users");
497 }
498 }
499 }
500
501 private bool ExistsFirstLastName(String fname, String lname)
502 {
503 string FindUser = "select * from users where (username=:username and surname=:surname)";
504 using (SqliteCommand cmd = new SqliteCommand(FindUser, g_conn))
505 {
506 cmd.Parameters.Add(new SqliteParameter(":username", fname));
507 cmd.Parameters.Add(new SqliteParameter(":surname", lname));
508 try
509 {
510 using (IDataReader reader = cmd.ExecuteReader())
511 {
512 if (reader.Read())
513 {
514 reader.Close();
515 return true;
516 }
517 else
518 {
519 reader.Close();
520 return false;
521 }
522 }
523 }
524 catch (Exception ex)
525 {
526 m_log.Error("[USER DB]: Exception searching for user's first and last name: " + ex.ToString());
527 return false;
528 }
529 }
530 }
531
532 /// <summary>
533 /// Creates a new user profile
534 /// </summary>
535 /// <param name="user">The profile to add to the database</param>
536 override public void AddNewUserProfile(UserProfileData user)
537 {
538 DataTable users = ds.Tables["users"];
539 UUID zero = UUID.Zero;
540 if (ExistsFirstLastName(user.FirstName, user.SurName) || user.ID == zero)
541 return;
542
543 lock (ds)
544 {
545 DataRow row = users.Rows.Find(user.ID.ToString());
546 if (row == null)
547 {
548 row = users.NewRow();
549 fillUserRow(row, user);
550 users.Rows.Add(row);
551
552 m_log.Debug("[USER DB]: Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored");
553
554 // save changes off to disk
555 da.Update(ds, "users");
556 }
557 else
558 {
559 m_log.WarnFormat("[USER DB]: Ignoring add since user with id {0} already exists", user.ID);
560 }
561 }
562 }
563
564 /// <summary>
565 /// Creates a new user profile
566 /// </summary>
567 /// <param name="user">The profile to add to the database</param>
568 /// <returns>True on success, false on error</returns>
569 override public bool UpdateUserProfile(UserProfileData user)
570 {
571 DataTable users = ds.Tables["users"];
572 lock (ds)
573 {
574 DataRow row = users.Rows.Find(user.ID.ToString());
575 if (row == null)
576 {
577 return false;
578 }
579 else
580 {
581 fillUserRow(row, user);
582 da.Update(ds, "users");
583 }
584 }
585
586 //AddNewUserProfile(user);
587 return true;
588 }
589
590 /// <summary>
591 /// Creates a new user agent
592 /// </summary>
593 /// <param name="agent">The agent to add to the database</param>
594 override public void AddNewUserAgent(UserAgentData agent)
595 {
596 UUID zero = UUID.Zero;
597 if (agent.SessionID == zero || agent.ProfileID == zero)
598 return;
599
600 DataTable agents = ds.Tables["useragents"];
601 lock (ds)
602 {
603 DataRow row = agents.Rows.Find(agent.ProfileID.ToString());
604 if (row == null)
605 {
606 row = agents.NewRow();
607 fillUserAgentRow(row, agent);
608 agents.Rows.Add(row);
609 }
610 else
611 {
612 fillUserAgentRow(row, agent);
613
614 }
615 m_log.Info("[USER DB]: Syncing useragent database: " + ds.Tables["useragents"].Rows.Count + " agents stored");
616 // save changes off to disk
617 dua.Update(ds, "useragents");
618 }
619 }
620
621 /// <summary>
622 /// Transfers money between two user accounts
623 /// </summary>
624 /// <param name="from">Starting account</param>
625 /// <param name="to">End account</param>
626 /// <param name="amount">The amount to move</param>
627 /// <returns>Success?</returns>
628 override public bool MoneyTransferRequest(UUID from, UUID to, uint amount)
629 {
630 return false; // for consistency with the MySQL impl
631 }
632
633 /// <summary>
634 /// Transfers inventory between two accounts
635 /// </summary>
636 /// <remarks>Move to inventory server</remarks>
637 /// <param name="from">Senders account</param>
638 /// <param name="to">Receivers account</param>
639 /// <param name="item">Inventory item</param>
640 /// <returns>Success?</returns>
641 override public bool InventoryTransferRequest(UUID from, UUID to, UUID item)
642 {
643 return false; //for consistency with the MySQL impl
644 }
645
646
647 /// <summary>
648 /// Appearance.
649 /// TODO: stubs for now to do in memory appearance.
650 /// </summary>
651 /// <param name="user">The user UUID</param>
652 /// <returns>Avatar Appearence</returns>
653 override public AvatarAppearance GetUserAppearance(UUID user)
654 {
655 m_log.Info("[APPEARANCE] GetUserAppearance " + user.ToString());
656
657 AvatarAppearance aa = new AvatarAppearance(user);
658 //try {
659 aa.Owner = user;
660
661 DataTable aap = ds.Tables["avatarappearance"];
662 lock (ds)
663 {
664 DataRow row = aap.Rows.Find(Util.ToRawUuidString(user));
665 if (row == null)
666 {
667 m_log.Info("[APPEARANCE] Could not find appearance for " + user.ToString());
668
669 //m_log.Debug("[USER DB]: Creating avatarappearance For: " + user.ToString());
670
671 //row = aap.NewRow();
672 //fillAvatarAppearanceRow(row, user, appearance);
673 //aap.Rows.Add(row);
674 // m_log.Debug("[USER DB]: Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored");
675 // save changes off to disk
676 //daa.Update(ds, "avatarappearance");
677 }
678 else
679 {
680 m_log.InfoFormat("[APPEARANCE] appearance found for {0}", user.ToString());
681
682 aa.BodyAsset = new UUID((String)row["BodyAsset"]);
683 aa.BodyItem = new UUID((String)row["BodyItem"]);
684 aa.SkinItem = new UUID((String)row["SkinItem"]);
685 aa.SkinAsset = new UUID((String)row["SkinAsset"]);
686 aa.HairItem = new UUID((String)row["HairItem"]);
687 aa.HairAsset = new UUID((String)row["HairAsset"]);
688 aa.EyesItem = new UUID((String)row["EyesItem"]);
689 aa.EyesAsset = new UUID((String)row["EyesAsset"]);
690 aa.ShirtItem = new UUID((String)row["ShirtItem"]);
691 aa.ShirtAsset = new UUID((String)row["ShirtAsset"]);
692 aa.PantsItem = new UUID((String)row["PantsItem"]);
693 aa.PantsAsset = new UUID((String)row["PantsAsset"]);
694 aa.ShoesItem = new UUID((String)row["ShoesItem"]);
695 aa.ShoesAsset = new UUID((String)row["ShoesAsset"]);
696 aa.SocksItem = new UUID((String)row["SocksItem"]);
697 aa.SocksAsset = new UUID((String)row["SocksAsset"]);
698 aa.JacketItem = new UUID((String)row["JacketItem"]);
699 aa.JacketAsset = new UUID((String)row["JacketAsset"]);
700 aa.GlovesItem = new UUID((String)row["GlovesItem"]);
701 aa.GlovesAsset = new UUID((String)row["GlovesAsset"]);
702 aa.UnderShirtItem = new UUID((String)row["UnderShirtItem"]);
703 aa.UnderShirtAsset = new UUID((String)row["UnderShirtAsset"]);
704 aa.UnderPantsItem = new UUID((String)row["UnderPantsItem"]);
705 aa.UnderPantsAsset = new UUID((String)row["UnderPantsAsset"]);
706 aa.SkirtItem = new UUID((String)row["SkirtItem"]);
707 aa.SkirtAsset = new UUID((String)row["SkirtAsset"]);
708
709 // Ewe Loon
710 // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date)
711
712 String str = (String)row["Texture"];
713 byte[] texture = Convert.FromBase64String(str);
714 aa.Texture = new Primitive.TextureEntry(texture, 0, texture.Length);
715
716 str = (String)row["VisualParams"];
717 byte[] VisualParams = Convert.FromBase64String(str);
718 aa.VisualParams = VisualParams;
719
720 aa.Serial = Convert.ToInt32(row["Serial"]);
721 aa.AvatarHeight = Convert.ToSingle(row["AvatarHeight"]);
722 m_log.InfoFormat("[APPEARANCE] appearance set for {0}", user.ToString());
723 }
724 }
725
726 // m_log.Info("[APPEARANCE] Found appearance for " + user.ToString() + aa.ToString());
727 // } catch (KeyNotFoundException) {
728 // m_log.InfoFormat("[APPEARANCE] No appearance found for {0}", user.ToString());
729 // }
730 return aa;
731 }
732
733 /// <summary>
734 /// Update a user appearence
735 /// </summary>
736 /// <param name="user">the user UUID</param>
737 /// <param name="appearance">appearence</param>
738 override public void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
739 {
740 appearance.Owner = user;
741 DataTable aap = ds.Tables["avatarappearance"];
742 lock (ds)
743 {
744 DataRow row = aap.Rows.Find(Util.ToRawUuidString(user));
745 if (row == null)
746 {
747 m_log.Debug("[USER DB]: Creating UserAppearance For: " + user.ToString());
748
749 row = aap.NewRow();
750 fillAvatarAppearanceRow(row, user, appearance);
751 aap.Rows.Add(row);
752 // m_log.Debug("[USER DB]: Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored");
753 // save changes off to disk
754 daa.Update(ds, "avatarappearance");
755 }
756 else
757 {
758 m_log.Debug("[USER DB]: Updating UserAppearance For: " + user.ToString());
759 fillAvatarAppearanceRow(row, user, appearance);
760 daa.Update(ds, "avatarappearance");
761 }
762 }
763 }
764
765 /// <summary>
766 /// Returns the name of the storage provider
767 /// </summary>
768 /// <returns>Storage provider name</returns>
769 override public string Name
770 {
771 get {return "Sqlite Userdata";}
772 }
773
774 /// <summary>
775 /// Returns the version of the storage provider
776 /// </summary>
777 /// <returns>Storage provider version</returns>
778 override public string Version
779 {
780 get {return "0.1";}
781 }
782
783 /***********************************************************************
784 *
785 * DataTable creation
786 *
787 **********************************************************************/
788 /***********************************************************************
789 *
790 * Database Definition Functions
791 *
792 * This should be db agnostic as we define them in ADO.NET terms
793 *
794 **********************************************************************/
795
796 /// <summary>
797 /// Create the "users" table
798 /// </summary>
799 /// <returns>DataTable</returns>
800 private static DataTable createUsersTable()
801 {
802 DataTable users = new DataTable("users");
803
804 SQLiteUtil.createCol(users, "UUID", typeof (String));
805 SQLiteUtil.createCol(users, "username", typeof (String));
806 SQLiteUtil.createCol(users, "surname", typeof (String));
807 SQLiteUtil.createCol(users, "email", typeof (String));
808 SQLiteUtil.createCol(users, "passwordHash", typeof (String));
809 SQLiteUtil.createCol(users, "passwordSalt", typeof (String));
810
811 SQLiteUtil.createCol(users, "homeRegionX", typeof (Int32));
812 SQLiteUtil.createCol(users, "homeRegionY", typeof (Int32));
813 SQLiteUtil.createCol(users, "homeRegionID", typeof (String));
814 SQLiteUtil.createCol(users, "homeLocationX", typeof (Double));
815 SQLiteUtil.createCol(users, "homeLocationY", typeof (Double));
816 SQLiteUtil.createCol(users, "homeLocationZ", typeof (Double));
817 SQLiteUtil.createCol(users, "homeLookAtX", typeof (Double));
818 SQLiteUtil.createCol(users, "homeLookAtY", typeof (Double));
819 SQLiteUtil.createCol(users, "homeLookAtZ", typeof (Double));
820 SQLiteUtil.createCol(users, "created", typeof (Int32));
821 SQLiteUtil.createCol(users, "lastLogin", typeof (Int32));
822
823 //TODO: Please delete this column. It's now a brick
824 SQLiteUtil.createCol(users, "rootInventoryFolderID", typeof (String));
825
826 SQLiteUtil.createCol(users, "userInventoryURI", typeof (String));
827 SQLiteUtil.createCol(users, "userAssetURI", typeof (String));
828 SQLiteUtil.createCol(users, "profileCanDoMask", typeof (Int32));
829 SQLiteUtil.createCol(users, "profileWantDoMask", typeof (Int32));
830 SQLiteUtil.createCol(users, "profileAboutText", typeof (String));
831 SQLiteUtil.createCol(users, "profileFirstText", typeof (String));
832 SQLiteUtil.createCol(users, "profileImage", typeof (String));
833 SQLiteUtil.createCol(users, "profileFirstImage", typeof (String));
834 SQLiteUtil.createCol(users, "webLoginKey", typeof(String));
835 SQLiteUtil.createCol(users, "userFlags", typeof (Int32));
836 SQLiteUtil.createCol(users, "godLevel", typeof (Int32));
837 SQLiteUtil.createCol(users, "customType", typeof (String));
838 SQLiteUtil.createCol(users, "partner", typeof (String));
839 // Add in contraints
840 users.PrimaryKey = new DataColumn[] {users.Columns["UUID"]};
841 return users;
842 }
843
844 /// <summary>
845 /// Create the "useragents" table
846 /// </summary>
847 /// <returns>Data Table</returns>
848 private static DataTable createUserAgentsTable()
849 {
850 DataTable ua = new DataTable("useragents");
851 // this is the UUID of the user
852 SQLiteUtil.createCol(ua, "UUID", typeof (String));
853 SQLiteUtil.createCol(ua, "agentIP", typeof (String));
854 SQLiteUtil.createCol(ua, "agentPort", typeof (Int32));
855 SQLiteUtil.createCol(ua, "agentOnline", typeof (Boolean));
856 SQLiteUtil.createCol(ua, "sessionID", typeof (String));
857 SQLiteUtil.createCol(ua, "secureSessionID", typeof (String));
858 SQLiteUtil.createCol(ua, "regionID", typeof (String));
859 SQLiteUtil.createCol(ua, "loginTime", typeof (Int32));
860 SQLiteUtil.createCol(ua, "logoutTime", typeof (Int32));
861 SQLiteUtil.createCol(ua, "currentRegion", typeof (String));
862 SQLiteUtil.createCol(ua, "currentHandle", typeof (String));
863 // vectors
864 SQLiteUtil.createCol(ua, "currentPosX", typeof (Double));
865 SQLiteUtil.createCol(ua, "currentPosY", typeof (Double));
866 SQLiteUtil.createCol(ua, "currentPosZ", typeof (Double));
867 // constraints
868 ua.PrimaryKey = new DataColumn[] {ua.Columns["UUID"]};
869
870 return ua;
871 }
872
873 /// <summary>
874 /// Create the "userfriends" table
875 /// </summary>
876 /// <returns>Data Table</returns>
877 private static DataTable createUserFriendsTable()
878 {
879 DataTable ua = new DataTable("userfriends");
880 // table contains user <----> user relationship with perms
881 SQLiteUtil.createCol(ua, "ownerID", typeof(String));
882 SQLiteUtil.createCol(ua, "friendID", typeof(String));
883 SQLiteUtil.createCol(ua, "friendPerms", typeof(Int32));
884 SQLiteUtil.createCol(ua, "ownerPerms", typeof(Int32));
885 SQLiteUtil.createCol(ua, "datetimestamp", typeof(Int32));
886
887 return ua;
888 }
889
890 /// <summary>
891 /// Create the "avatarappearance" table
892 /// </summary>
893 /// <returns>Data Table</returns>
894 private static DataTable createAvatarAppearanceTable()
895 {
896 DataTable aa = new DataTable("avatarappearance");
897 // table contains user appearance items
898
899 SQLiteUtil.createCol(aa, "Owner", typeof(String));
900 SQLiteUtil.createCol(aa, "BodyItem", typeof(String));
901 SQLiteUtil.createCol(aa, "BodyAsset", typeof(String));
902 SQLiteUtil.createCol(aa, "SkinItem", typeof(String));
903 SQLiteUtil.createCol(aa, "SkinAsset", typeof(String));
904 SQLiteUtil.createCol(aa, "HairItem", typeof(String));
905 SQLiteUtil.createCol(aa, "HairAsset", typeof(String));
906 SQLiteUtil.createCol(aa, "EyesItem", typeof(String));
907 SQLiteUtil.createCol(aa, "EyesAsset", typeof(String));
908 SQLiteUtil.createCol(aa, "ShirtItem", typeof(String));
909 SQLiteUtil.createCol(aa, "ShirtAsset", typeof(String));
910 SQLiteUtil.createCol(aa, "PantsItem", typeof(String));
911 SQLiteUtil.createCol(aa, "PantsAsset", typeof(String));
912 SQLiteUtil.createCol(aa, "ShoesItem", typeof(String));
913 SQLiteUtil.createCol(aa, "ShoesAsset", typeof(String));
914 SQLiteUtil.createCol(aa, "SocksItem", typeof(String));
915 SQLiteUtil.createCol(aa, "SocksAsset", typeof(String));
916 SQLiteUtil.createCol(aa, "JacketItem", typeof(String));
917 SQLiteUtil.createCol(aa, "JacketAsset", typeof(String));
918 SQLiteUtil.createCol(aa, "GlovesItem", typeof(String));
919 SQLiteUtil.createCol(aa, "GlovesAsset", typeof(String));
920 SQLiteUtil.createCol(aa, "UnderShirtItem", typeof(String));
921 SQLiteUtil.createCol(aa, "UnderShirtAsset", typeof(String));
922 SQLiteUtil.createCol(aa, "UnderPantsItem", typeof(String));
923 SQLiteUtil.createCol(aa, "UnderPantsAsset", typeof(String));
924 SQLiteUtil.createCol(aa, "SkirtItem", typeof(String));
925 SQLiteUtil.createCol(aa, "SkirtAsset", typeof(String));
926
927 // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date)
928 SQLiteUtil.createCol(aa, "Texture", typeof (String));
929 SQLiteUtil.createCol(aa, "VisualParams", typeof (String));
930
931 SQLiteUtil.createCol(aa, "Serial", typeof(Int32));
932 SQLiteUtil.createCol(aa, "AvatarHeight", typeof(Double));
933
934 aa.PrimaryKey = new DataColumn[] { aa.Columns["Owner"] };
935
936 return aa;
937 }
938
939 /***********************************************************************
940 *
941 * Convert between ADO.NET <=> OpenSim Objects
942 *
943 * These should be database independant
944 *
945 **********************************************************************/
946
947 /// <summary>
948 /// TODO: this doesn't work yet because something more
949 /// interesting has to be done to actually get these values
950 /// back out. Not enough time to figure it out yet.
951 /// </summary>
952 /// <param name="row"></param>
953 /// <returns></returns>
954 private static UserProfileData buildUserProfile(DataRow row)
955 {
956 UserProfileData user = new UserProfileData();
957 UUID tmp;
958 UUID.TryParse((String)row["UUID"], out tmp);
959 user.ID = tmp;
960 user.FirstName = (String) row["username"];
961 user.SurName = (String) row["surname"];
962 user.Email = (row.IsNull("email")) ? "" : (String) row["email"];
963
964 user.PasswordHash = (String) row["passwordHash"];
965 user.PasswordSalt = (String) row["passwordSalt"];
966
967 user.HomeRegionX = Convert.ToUInt32(row["homeRegionX"]);
968 user.HomeRegionY = Convert.ToUInt32(row["homeRegionY"]);
969 user.HomeLocation = new Vector3(
970 Convert.ToSingle(row["homeLocationX"]),
971 Convert.ToSingle(row["homeLocationY"]),
972 Convert.ToSingle(row["homeLocationZ"])
973 );
974 user.HomeLookAt = new Vector3(
975 Convert.ToSingle(row["homeLookAtX"]),
976 Convert.ToSingle(row["homeLookAtY"]),
977 Convert.ToSingle(row["homeLookAtZ"])
978 );
979
980 UUID regionID = UUID.Zero;
981 UUID.TryParse(row["homeRegionID"].ToString(), out regionID); // it's ok if it doesn't work; just use UUID.Zero
982 user.HomeRegionID = regionID;
983
984 user.Created = Convert.ToInt32(row["created"]);
985 user.LastLogin = Convert.ToInt32(row["lastLogin"]);
986 user.UserInventoryURI = (String) row["userInventoryURI"];
987 user.UserAssetURI = (String) row["userAssetURI"];
988 user.CanDoMask = Convert.ToUInt32(row["profileCanDoMask"]);
989 user.WantDoMask = Convert.ToUInt32(row["profileWantDoMask"]);
990 user.AboutText = (String) row["profileAboutText"];
991 user.FirstLifeAboutText = (String) row["profileFirstText"];
992 UUID.TryParse((String)row["profileImage"], out tmp);
993 user.Image = tmp;
994 UUID.TryParse((String)row["profileFirstImage"], out tmp);
995 user.FirstLifeImage = tmp;
996 user.WebLoginKey = new UUID((String) row["webLoginKey"]);
997 user.UserFlags = Convert.ToInt32(row["userFlags"]);
998 user.GodLevel = Convert.ToInt32(row["godLevel"]);
999 user.CustomType = row["customType"].ToString();
1000 user.Partner = new UUID((String) row["partner"]);
1001
1002 return user;
1003 }
1004
1005 /// <summary>
1006 /// Persist user profile data
1007 /// </summary>
1008 /// <param name="row"></param>
1009 /// <param name="user"></param>
1010 private void fillUserRow(DataRow row, UserProfileData user)
1011 {
1012 row["UUID"] = user.ID.ToString();
1013 row["username"] = user.FirstName;
1014 row["surname"] = user.SurName;
1015 row["email"] = user.Email;
1016 row["passwordHash"] = user.PasswordHash;
1017 row["passwordSalt"] = user.PasswordSalt;
1018
1019 row["homeRegionX"] = user.HomeRegionX;
1020 row["homeRegionY"] = user.HomeRegionY;
1021 row["homeRegionID"] = user.HomeRegionID.ToString();
1022 row["homeLocationX"] = user.HomeLocation.X;
1023 row["homeLocationY"] = user.HomeLocation.Y;
1024 row["homeLocationZ"] = user.HomeLocation.Z;
1025 row["homeLookAtX"] = user.HomeLookAt.X;
1026 row["homeLookAtY"] = user.HomeLookAt.Y;
1027 row["homeLookAtZ"] = user.HomeLookAt.Z;
1028
1029 row["created"] = user.Created;
1030 row["lastLogin"] = user.LastLogin;
1031 //TODO: Get rid of rootInventoryFolderID in a safe way.
1032 row["rootInventoryFolderID"] = UUID.Zero.ToString();
1033 row["userInventoryURI"] = user.UserInventoryURI;
1034 row["userAssetURI"] = user.UserAssetURI;
1035 row["profileCanDoMask"] = user.CanDoMask;
1036 row["profileWantDoMask"] = user.WantDoMask;
1037 row["profileAboutText"] = user.AboutText;
1038 row["profileFirstText"] = user.FirstLifeAboutText;
1039 row["profileImage"] = user.Image.ToString();
1040 row["profileFirstImage"] = user.FirstLifeImage.ToString();
1041 row["webLoginKey"] = user.WebLoginKey.ToString();
1042 row["userFlags"] = user.UserFlags;
1043 row["godLevel"] = user.GodLevel;
1044 row["customType"] = user.CustomType == null ? "" : user.CustomType;
1045 row["partner"] = user.Partner.ToString();
1046
1047 // ADO.NET doesn't handle NULL very well
1048 foreach (DataColumn col in ds.Tables["users"].Columns)
1049 {
1050 if (row[col] == null)
1051 {
1052 row[col] = String.Empty;
1053 }
1054 }
1055 }
1056
1057 /// <summary>
1058 ///
1059 /// </summary>
1060 /// <param name="row"></param>
1061 /// <param name="user"></param>
1062 private void fillAvatarAppearanceRow(DataRow row, UUID user, AvatarAppearance appearance)
1063 {
1064 row["Owner"] = Util.ToRawUuidString(user);
1065 row["BodyItem"] = appearance.BodyItem.ToString();
1066 row["BodyAsset"] = appearance.BodyAsset.ToString();
1067 row["SkinItem"] = appearance.SkinItem.ToString();
1068 row["SkinAsset"] = appearance.SkinAsset.ToString();
1069 row["HairItem"] = appearance.HairItem.ToString();
1070 row["HairAsset"] = appearance.HairAsset.ToString();
1071 row["EyesItem"] = appearance.EyesItem.ToString();
1072 row["EyesAsset"] = appearance.EyesAsset.ToString();
1073 row["ShirtItem"] = appearance.ShirtItem.ToString();
1074 row["ShirtAsset"] = appearance.ShirtAsset.ToString();
1075 row["PantsItem"] = appearance.PantsItem.ToString();
1076 row["PantsAsset"] = appearance.PantsAsset.ToString();
1077 row["ShoesItem"] = appearance.ShoesItem.ToString();
1078 row["ShoesAsset"] = appearance.ShoesAsset.ToString();
1079 row["SocksItem"] = appearance.SocksItem.ToString();
1080 row["SocksAsset"] = appearance.SocksAsset.ToString();
1081 row["JacketItem"] = appearance.JacketItem.ToString();
1082 row["JacketAsset"] = appearance.JacketAsset.ToString();
1083 row["GlovesItem"] = appearance.GlovesItem.ToString();
1084 row["GlovesAsset"] = appearance.GlovesAsset.ToString();
1085 row["UnderShirtItem"] = appearance.UnderShirtItem.ToString();
1086 row["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString();
1087 row["UnderPantsItem"] = appearance.UnderPantsItem.ToString();
1088 row["UnderPantsAsset"] = appearance.UnderPantsAsset.ToString();
1089 row["SkirtItem"] = appearance.SkirtItem.ToString();
1090 row["SkirtAsset"] = appearance.SkirtAsset.ToString();
1091
1092 // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date)
1093 row["Texture"] = Convert.ToBase64String(appearance.Texture.GetBytes());
1094 row["VisualParams"] = Convert.ToBase64String(appearance.VisualParams);
1095
1096 row["Serial"] = appearance.Serial;
1097 row["AvatarHeight"] = appearance.AvatarHeight;
1098
1099 // ADO.NET doesn't handle NULL very well
1100 foreach (DataColumn col in ds.Tables["avatarappearance"].Columns)
1101 {
1102 if (row[col] == null)
1103 {
1104 row[col] = String.Empty;
1105 }
1106 }
1107 }
1108
1109 /// <summary>
1110 ///
1111 /// </summary>
1112 /// <param name="row"></param>
1113 /// <returns></returns>
1114 private static UserAgentData buildUserAgent(DataRow row)
1115 {
1116 UserAgentData ua = new UserAgentData();
1117
1118 UUID tmp;
1119 UUID.TryParse((String)row["UUID"], out tmp);
1120 ua.ProfileID = tmp;
1121 ua.AgentIP = (String)row["agentIP"];
1122 ua.AgentPort = Convert.ToUInt32(row["agentPort"]);
1123 ua.AgentOnline = Convert.ToBoolean(row["agentOnline"]);
1124 ua.SessionID = new UUID((String) row["sessionID"]);
1125 ua.SecureSessionID = new UUID((String) row["secureSessionID"]);
1126 ua.InitialRegion = new UUID((String) row["regionID"]);
1127 ua.LoginTime = Convert.ToInt32(row["loginTime"]);
1128 ua.LogoutTime = Convert.ToInt32(row["logoutTime"]);
1129 ua.Region = new UUID((String) row["currentRegion"]);
1130 ua.Handle = Convert.ToUInt64(row["currentHandle"]);
1131 ua.Position = new Vector3(
1132 Convert.ToSingle(row["currentPosX"]),
1133 Convert.ToSingle(row["currentPosY"]),
1134 Convert.ToSingle(row["currentPosZ"])
1135 );
1136 ua.LookAt = new Vector3(
1137 Convert.ToSingle(row["currentLookAtX"]),
1138 Convert.ToSingle(row["currentLookAtY"]),
1139 Convert.ToSingle(row["currentLookAtZ"])
1140 );
1141 return ua;
1142 }
1143
1144 /// <summary>
1145 ///
1146 /// </summary>
1147 /// <param name="row"></param>
1148 /// <param name="ua"></param>
1149 private static void fillUserAgentRow(DataRow row, UserAgentData ua)
1150 {
1151 row["UUID"] = ua.ProfileID.ToString();
1152 row["agentIP"] = ua.AgentIP;
1153 row["agentPort"] = ua.AgentPort;
1154 row["agentOnline"] = ua.AgentOnline;
1155 row["sessionID"] = ua.SessionID.ToString();
1156 row["secureSessionID"] = ua.SecureSessionID.ToString();
1157 row["regionID"] = ua.InitialRegion.ToString();
1158 row["loginTime"] = ua.LoginTime;
1159 row["logoutTime"] = ua.LogoutTime;
1160 row["currentRegion"] = ua.Region.ToString();
1161 row["currentHandle"] = ua.Handle.ToString();
1162 // vectors
1163 row["currentPosX"] = ua.Position.X;
1164 row["currentPosY"] = ua.Position.Y;
1165 row["currentPosZ"] = ua.Position.Z;
1166 row["currentLookAtX"] = ua.LookAt.X;
1167 row["currentLookAtY"] = ua.LookAt.Y;
1168 row["currentLookAtZ"] = ua.LookAt.Z;
1169 }
1170
1171 /***********************************************************************
1172 *
1173 * Database Binding functions
1174 *
1175 * These will be db specific due to typing, and minor differences
1176 * in databases.
1177 *
1178 **********************************************************************/
1179
1180 /// <summary>
1181 ///
1182 /// </summary>
1183 /// <param name="da"></param>
1184 /// <param name="conn"></param>
1185 private void setupUserCommands(SqliteDataAdapter da, SqliteConnection conn)
1186 {
1187 da.InsertCommand = SQLiteUtil.createInsertCommand("users", ds.Tables["users"]);
1188 da.InsertCommand.Connection = conn;
1189
1190 da.UpdateCommand = SQLiteUtil.createUpdateCommand("users", "UUID=:UUID", ds.Tables["users"]);
1191 da.UpdateCommand.Connection = conn;
1192
1193 SqliteCommand delete = new SqliteCommand("delete from users where UUID = :UUID");
1194 delete.Parameters.Add(SQLiteUtil.createSqliteParameter("UUID", typeof(String)));
1195 delete.Connection = conn;
1196 da.DeleteCommand = delete;
1197 }
1198
1199 private void setupAgentCommands(SqliteDataAdapter da, SqliteConnection conn)
1200 {
1201 da.InsertCommand = SQLiteUtil.createInsertCommand("useragents", ds.Tables["useragents"]);
1202 da.InsertCommand.Connection = conn;
1203
1204 da.UpdateCommand = SQLiteUtil.createUpdateCommand("useragents", "UUID=:UUID", ds.Tables["useragents"]);
1205 da.UpdateCommand.Connection = conn;
1206
1207 SqliteCommand delete = new SqliteCommand("delete from useragents where UUID = :ProfileID");
1208 delete.Parameters.Add(SQLiteUtil.createSqliteParameter("ProfileID", typeof(String)));
1209 delete.Connection = conn;
1210 da.DeleteCommand = delete;
1211 }
1212
1213 /// <summary>
1214 ///
1215 /// </summary>
1216 /// <param name="daf"></param>
1217 /// <param name="conn"></param>
1218 private void setupUserFriendsCommands(SqliteDataAdapter daf, SqliteConnection conn)
1219 {
1220 daf.InsertCommand = SQLiteUtil.createInsertCommand("userfriends", ds.Tables["userfriends"]);
1221 daf.InsertCommand.Connection = conn;
1222
1223 daf.UpdateCommand = SQLiteUtil.createUpdateCommand("userfriends", "ownerID=:ownerID and friendID=:friendID", ds.Tables["userfriends"]);
1224 daf.UpdateCommand.Connection = conn;
1225
1226 SqliteCommand delete = new SqliteCommand("delete from userfriends where ownerID=:ownerID and friendID=:friendID");
1227 delete.Parameters.Add(SQLiteUtil.createSqliteParameter("ownerID", typeof(String)));
1228 delete.Parameters.Add(SQLiteUtil.createSqliteParameter("friendID", typeof(String)));
1229 delete.Connection = conn;
1230 daf.DeleteCommand = delete;
1231
1232 }
1233
1234 /// <summary>
1235 ///
1236 /// </summary>
1237 /// <param name="daf"></param>
1238 /// <param name="conn"></param>
1239 private void setupAvatarAppearanceCommands(SqliteDataAdapter daa, SqliteConnection conn)
1240 {
1241 daa.InsertCommand = SQLiteUtil.createInsertCommand("avatarappearance", ds.Tables["avatarappearance"]);
1242 daa.InsertCommand.Connection = conn;
1243
1244 daa.UpdateCommand = SQLiteUtil.createUpdateCommand("avatarappearance", "Owner=:Owner", ds.Tables["avatarappearance"]);
1245 daa.UpdateCommand.Connection = conn;
1246
1247 SqliteCommand delete = new SqliteCommand("delete from avatarappearance where Owner=:Owner");
1248 delete.Parameters.Add(SQLiteUtil.createSqliteParameter("Owner", typeof(String)));
1249 delete.Connection = conn;
1250 daa.DeleteCommand = delete;
1251 }
1252
1253
1254 override public void ResetAttachments(UUID userID)
1255 {
1256 }
1257
1258 override public void LogoutUsers(UUID regionID)
1259 {
1260 }
1261 }
1262}
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
index 5c93f88..a66e0c6 100644
--- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
+++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
@@ -115,7 +115,7 @@ namespace OpenSim.Data.SQLite
115 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); 115 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
116 cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); 116 cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
117 117
118 return ExecuteNonQuery(cmd) == 0 ? false : true; 118 return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
119 } 119 }
120 120
121 public XInventoryItem[] GetActiveGestures(UUID principalID) 121 public XInventoryItem[] GetActiveGestures(UUID principalID)
@@ -137,7 +137,7 @@ namespace OpenSim.Data.SQLite
137 cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); 137 cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
138 cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString())); 138 cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString()));
139 139
140 IDataReader reader = ExecuteReader(cmd); 140 IDataReader reader = ExecuteReader(cmd, m_Connection);
141 141
142 int perms = 0; 142 int perms = 0;
143 143
@@ -147,7 +147,7 @@ namespace OpenSim.Data.SQLite
147 } 147 }
148 148
149 reader.Close(); 149 reader.Close();
150 CloseReaderCommand(cmd); 150 CloseCommand(cmd);
151 151
152 return perms; 152 return perms;
153 } 153 }
diff --git a/OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs b/OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs
deleted file mode 100644
index c9953c5..0000000
--- a/OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using NUnit.Framework;
30using OpenSim.Data.Tests;
31using OpenSim.Tests.Common;
32
33namespace OpenSim.Data.SQLite.Tests
34{
35 [TestFixture, DatabaseTest]
36 public class SQLiteUserTest : BasicUserTest
37 {
38 public string file;
39 public string connect;
40
41 [TestFixtureSetUp]
42 public void Init()
43 {
44 // SQLite doesn't work on power or z linux
45 if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
46 {
47 Assert.Ignore();
48 }
49
50 SuperInit();
51 file = Path.GetTempFileName() + ".db";
52 connect = "URI=file:" + file + ",version=3";
53 db = new SQLiteUserData();
54 db.Initialise(connect);
55 }
56
57 [TestFixtureTearDown]
58 public void Cleanup()
59 {
60 db.Dispose();
61 File.Delete(file);
62 }
63 }
64}
diff --git a/OpenSim/Region/Communications/Local/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
index c631bf7..4aeb67b 100644
--- a/OpenSim/Region/Communications/Local/Properties/AssemblyInfo.cs
+++ b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
@@ -32,11 +32,11 @@ using System.Runtime.InteropServices;
32// set of attributes. Change these attribute values to modify the information 32// set of attributes. Change these attribute values to modify the information
33// associated with an assembly. 33// associated with an assembly.
34 34
35[assembly : AssemblyTitle("OpenSim.Region.Communications.Local")] 35[assembly : AssemblyTitle("OpenSim.Data.SQLiteNG")]
36[assembly : AssemblyDescription("")] 36[assembly : AssemblyDescription("")]
37[assembly : AssemblyConfiguration("")] 37[assembly : AssemblyConfiguration("")]
38[assembly : AssemblyCompany("http://opensimulator.org")] 38[assembly : AssemblyCompany("http://opensimulator.org")]
39[assembly : AssemblyProduct("OpenSim.Region.Communications.Local")] 39[assembly : AssemblyProduct("OpenSim.Data.SQLiteNG")]
40[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] 40[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
41[assembly : AssemblyTrademark("")] 41[assembly : AssemblyTrademark("")]
42[assembly : AssemblyCulture("")] 42[assembly : AssemblyCulture("")]
@@ -49,7 +49,7 @@ using System.Runtime.InteropServices;
49 49
50// The following GUID is for the ID of the typelib if this project is exposed to COM 50// The following GUID is for the ID of the typelib if this project is exposed to COM
51 51
52[assembly : Guid("fb173926-bd0a-4cd0-bb45-185b2f72ddfb")] 52[assembly : Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")]
53 53
54// Version information for an assembly consists of the following four values: 54// Version information for an assembly consists of the following four values:
55// 55//
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
new file mode 100644
index 0000000..2e026ca
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
@@ -0,0 +1,12 @@
1BEGIN TRANSACTION;
2CREATE TABLE assets(
3 UUID varchar(255) primary key,
4 Name varchar(255),
5 Description varchar(255),
6 Type integer,
7 InvType integer,
8 Local integer,
9 Temporary integer,
10 Data blob);
11
12COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
new file mode 100644
index 0000000..468567d
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
@@ -0,0 +1,18 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE auth (
4 UUID char(36) NOT NULL,
5 passwordHash char(32) NOT NULL default '',
6 passwordSalt char(32) NOT NULL default '',
7 webLoginKey varchar(255) NOT NULL default '',
8 accountType VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
9 PRIMARY KEY (`UUID`)
10);
11
12CREATE TABLE tokens (
13 UUID char(36) NOT NULL,
14 token varchar(255) NOT NULL,
15 validity datetime NOT NULL
16);
17
18COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql b/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
new file mode 100644
index 0000000..7ec906b
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
@@ -0,0 +1,9 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE Avatars (
4 PrincipalID CHAR(36) NOT NULL,
5 Name VARCHAR(32) NOT NULL,
6 Value VARCHAR(255) NOT NULL DEFAULT '',
7 PRIMARY KEY(PrincipalID, Name));
8
9COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
new file mode 100644
index 0000000..f1b9ab9
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
@@ -0,0 +1,10 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE `Friends` (
4 `PrincipalID` CHAR(36) NOT NULL,
5 `Friend` VARCHAR(255) NOT NULL,
6 `Flags` VARCHAR(16) NOT NULL DEFAULT 0,
7 `Offered` VARCHAR(32) NOT NULL DEFAULT 0,
8 PRIMARY KEY(`PrincipalID`, `Friend`));
9
10COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
new file mode 100644
index 0000000..554d5c2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
@@ -0,0 +1,32 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE inventoryfolders(
4 UUID varchar(255) primary key,
5 name varchar(255),
6 agentID varchar(255),
7 parentID varchar(255),
8 type integer,
9 version integer);
10
11CREATE TABLE inventoryitems(
12 UUID varchar(255) primary key,
13 assetID varchar(255),
14 assetType integer,
15 invType integer,
16 parentFolderID varchar(255),
17 avatarID varchar(255),
18 creatorsID varchar(255),
19 inventoryName varchar(255),
20 inventoryDescription varchar(255),
21 inventoryNextPermissions integer,
22 inventoryCurrentPermissions integer,
23 inventoryBasePermissions integer,
24 inventoryEveryOnePermissions integer,
25 salePrice integer default 99,
26 saleType integer default 0,
27 creationDate integer default 2000,
28 groupID varchar(255) default '00000000-0000-0000-0000-000000000000',
29 groupOwned integer default 0,
30 flags integer default 0);
31
32COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
new file mode 100644
index 0000000..39e8180
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
@@ -0,0 +1,144 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE prims(
4 UUID varchar(255) primary key,
5 RegionUUID varchar(255),
6 ParentID integer,
7 CreationDate integer,
8 Name varchar(255),
9 SceneGroupID varchar(255),
10 Text varchar(255),
11 Description varchar(255),
12 SitName varchar(255),
13 TouchName varchar(255),
14 CreatorID varchar(255),
15 OwnerID varchar(255),
16 GroupID varchar(255),
17 LastOwnerID varchar(255),
18 OwnerMask integer,
19 NextOwnerMask integer,
20 GroupMask integer,
21 EveryoneMask integer,
22 BaseMask integer,
23 PositionX float,
24 PositionY float,
25 PositionZ float,
26 GroupPositionX float,
27 GroupPositionY float,
28 GroupPositionZ float,
29 VelocityX float,
30 VelocityY float,
31 VelocityZ float,
32 AngularVelocityX float,
33 AngularVelocityY float,
34 AngularVelocityZ float,
35 AccelerationX float,
36 AccelerationY float,
37 AccelerationZ float,
38 RotationX float,
39 RotationY float,
40 RotationZ float,
41 RotationW float,
42 ObjectFlags integer,
43 SitTargetOffsetX float NOT NULL default 0,
44 SitTargetOffsetY float NOT NULL default 0,
45 SitTargetOffsetZ float NOT NULL default 0,
46 SitTargetOrientW float NOT NULL default 0,
47 SitTargetOrientX float NOT NULL default 0,
48 SitTargetOrientY float NOT NULL default 0,
49 SitTargetOrientZ float NOT NULL default 0);
50
51CREATE TABLE primshapes(
52 UUID varchar(255) primary key,
53 Shape integer,
54 ScaleX float,
55 ScaleY float,
56 ScaleZ float,
57 PCode integer,
58 PathBegin integer,
59 PathEnd integer,
60 PathScaleX integer,
61 PathScaleY integer,
62 PathShearX integer,
63 PathShearY integer,
64 PathSkew integer,
65 PathCurve integer,
66 PathRadiusOffset integer,
67 PathRevolutions integer,
68 PathTaperX integer,
69 PathTaperY integer,
70 PathTwist integer,
71 PathTwistBegin integer,
72 ProfileBegin integer,
73 ProfileEnd integer,
74 ProfileCurve integer,
75 ProfileHollow integer,
76 Texture blob,
77 ExtraParams blob,
78 State Integer NOT NULL default 0);
79
80CREATE TABLE primitems(
81 itemID varchar(255) primary key,
82 primID varchar(255),
83 assetID varchar(255),
84 parentFolderID varchar(255),
85 invType integer,
86 assetType integer,
87 name varchar(255),
88 description varchar(255),
89 creationDate integer,
90 creatorID varchar(255),
91 ownerID varchar(255),
92 lastOwnerID varchar(255),
93 groupID varchar(255),
94 nextPermissions string,
95 currentPermissions string,
96 basePermissions string,
97 everyonePermissions string,
98 groupPermissions string);
99
100CREATE TABLE terrain(
101 RegionUUID varchar(255),
102 Revision integer,
103 Heightfield blob);
104
105CREATE TABLE land(
106 UUID varchar(255) primary key,
107 RegionUUID varchar(255),
108 LocalLandID string,
109 Bitmap blob,
110 Name varchar(255),
111 Desc varchar(255),
112 OwnerUUID varchar(255),
113 IsGroupOwned string,
114 Area integer,
115 AuctionID integer,
116 Category integer,
117 ClaimDate integer,
118 ClaimPrice integer,
119 GroupUUID varchar(255),
120 SalePrice integer,
121 LandStatus integer,
122 LandFlags string,
123 LandingType string,
124 MediaAutoScale string,
125 MediaTextureUUID varchar(255),
126 MediaURL varchar(255),
127 MusicURL varchar(255),
128 PassHours float,
129 PassPrice string,
130 SnapshotUUID varchar(255),
131 UserLocationX float,
132 UserLocationY float,
133 UserLocationZ float,
134 UserLookAtX float,
135 UserLookAtY float,
136 UserLookAtZ float,
137 AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000');
138
139CREATE TABLE landaccesslist(
140 LandUUID varchar(255),
141 AccessUUID varchar(255),
142 Flags string);
143
144COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql b/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
new file mode 100644
index 0000000..c38d9a7
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
@@ -0,0 +1,17 @@
1BEGIN TRANSACTION;
2
3-- useraccounts table
4CREATE TABLE UserAccounts (
5 PrincipalID CHAR(36) primary key,
6 ScopeID CHAR(36) NOT NULL,
7 FirstName VARCHAR(64) NOT NULL,
8 LastName VARCHAR(64) NOT NULL,
9 Email VARCHAR(64),
10 ServiceURLs TEXT,
11 Created INT(11),
12 UserLevel integer NOT NULL DEFAULT 0,
13 UserFlags integer NOT NULL DEFAULT 0,
14 UserTitle varchar(64) NOT NULL DEFAULT ''
15);
16
17COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
new file mode 100644
index 0000000..b584594
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
@@ -0,0 +1,39 @@
1BEGIN TRANSACTION;
2
3-- users table
4CREATE TABLE users(
5 UUID varchar(255) primary key,
6 username varchar(255),
7 surname varchar(255),
8 passwordHash varchar(255),
9 passwordSalt varchar(255),
10 homeRegionX integer,
11 homeRegionY integer,
12 homeLocationX float,
13 homeLocationY float,
14 homeLocationZ float,
15 homeLookAtX float,
16 homeLookAtY float,
17 homeLookAtZ float,
18 created integer,
19 lastLogin integer,
20 rootInventoryFolderID varchar(255),
21 userInventoryURI varchar(255),
22 userAssetURI varchar(255),
23 profileCanDoMask integer,
24 profileWantDoMask integer,
25 profileAboutText varchar(255),
26 profileFirstText varchar(255),
27 profileImage varchar(255),
28 profileFirstImage varchar(255),
29 webLoginKey text default '00000000-0000-0000-0000-000000000000');
30-- friends table
31CREATE TABLE userfriends(
32 ownerID varchar(255),
33 friendID varchar(255),
34 friendPerms integer,
35 ownerPerms integer,
36 datetimestamp integer);
37
38COMMIT;
39
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
new file mode 100644
index 0000000..5339b84
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
@@ -0,0 +1,10 @@
1BEGIN TRANSACTION;
2
3CREATE TEMPORARY TABLE assets_backup(UUID,Name,Description,Type,Local,Temporary,Data);
4INSERT INTO assets_backup SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets;
5DROP TABLE assets;
6CREATE TABLE assets(UUID,Name,Description,Type,Local,Temporary,Data);
7INSERT INTO assets SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets_backup;
8DROP TABLE assets_backup;
9
10COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
new file mode 100644
index 0000000..3237b68
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
new file mode 100644
index 0000000..6733502
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
new file mode 100644
index 0000000..01951d6
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
@@ -0,0 +1,8 @@
1BEGIN TRANSACTION;
2
3create index inventoryfolders_agentid on inventoryfolders(agentid);
4create index inventoryfolders_parentid on inventoryfolders(parentid);
5create index inventoryitems_parentfolderid on inventoryitems(parentfolderid);
6create index inventoryitems_avatarid on inventoryitems(avatarid);
7
8COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
new file mode 100644
index 0000000..c5c7c99
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
@@ -0,0 +1,10 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE regionban(
4 regionUUID varchar (255),
5 bannedUUID varchar (255),
6 bannedIp varchar (255),
7 bannedIpHostMask varchar (255)
8 );
9
10COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql b/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
new file mode 100644
index 0000000..c7a6293
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, surname AS LastName, '' as Email, '' AS ServiceURLs, created as Created FROM users;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
new file mode 100644
index 0000000..48fc680
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE users add homeRegionID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
new file mode 100644
index 0000000..f54f8d9
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
@@ -0,0 +1 @@
DELETE FROM assets WHERE UUID = 'dc4b9f0bd00845c696a401dd947ac621'
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
new file mode 100644
index 0000000..4c6da91
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3alter table inventoryitems add column inventoryGroupPermissions integer unsigned not null default 0;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
new file mode 100644
index 0000000..4db2f75
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE primitems add flags integer not null default 0;
4
5COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
new file mode 100644
index 0000000..6f890ee
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
@@ -0,0 +1,6 @@
1BEGIN;
2
3ALTER TABLE users add userFlags integer NOT NULL default 0;
4ALTER TABLE users add godLevel integer NOT NULL default 0;
5
6COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
new file mode 100644
index 0000000..39421c4
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
@@ -0,0 +1,7 @@
1BEGIN;
2
3update assets
4 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
5 where UUID not like '%-%';
6
7COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
new file mode 100644
index 0000000..e8f4d46
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
@@ -0,0 +1,36 @@
1BEGIN;
2
3update inventoryitems
4 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
5 where UUID not like '%-%';
6
7update inventoryitems
8 set assetID = substr(assetID, 1, 8) || "-" || substr(assetID, 9, 4) || "-" || substr(assetID, 13, 4) || "-" || substr(assetID, 17, 4) || "-" || substr(assetID, 21, 12)
9 where assetID not like '%-%';
10
11update inventoryitems
12 set parentFolderID = substr(parentFolderID, 1, 8) || "-" || substr(parentFolderID, 9, 4) || "-" || substr(parentFolderID, 13, 4) || "-" || substr(parentFolderID, 17, 4) || "-" || substr(parentFolderID, 21, 12)
13 where parentFolderID not like '%-%';
14
15update inventoryitems
16 set avatarID = substr(avatarID, 1, 8) || "-" || substr(avatarID, 9, 4) || "-" || substr(avatarID, 13, 4) || "-" || substr(avatarID, 17, 4) || "-" || substr(avatarID, 21, 12)
17 where avatarID not like '%-%';
18
19update inventoryitems
20 set creatorsID = substr(creatorsID, 1, 8) || "-" || substr(creatorsID, 9, 4) || "-" || substr(creatorsID, 13, 4) || "-" || substr(creatorsID, 17, 4) || "-" || substr(creatorsID, 21, 12)
21 where creatorsID not like '%-%';
22
23
24update inventoryfolders
25 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
26 where UUID not like '%-%';
27
28update inventoryfolders
29 set agentID = substr(agentID, 1, 8) || "-" || substr(agentID, 9, 4) || "-" || substr(agentID, 13, 4) || "-" || substr(agentID, 17, 4) || "-" || substr(agentID, 21, 12)
30 where agentID not like '%-%';
31
32update inventoryfolders
33 set parentID = substr(parentID, 1, 8) || "-" || substr(parentID, 9, 4) || "-" || substr(parentID, 13, 4) || "-" || substr(parentID, 17, 4) || "-" || substr(parentID, 21, 12)
34 where parentID not like '%-%';
35
36COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
new file mode 100644
index 0000000..de328cb
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
@@ -0,0 +1,38 @@
1BEGIN;
2
3create table regionsettings (
4 regionUUID char(36) not null,
5 block_terraform integer not null,
6 block_fly integer not null,
7 allow_damage integer not null,
8 restrict_pushing integer not null,
9 allow_land_resell integer not null,
10 allow_land_join_divide integer not null,
11 block_show_in_search integer not null,
12 agent_limit integer not null,
13 object_bonus float not null,
14 maturity integer not null,
15 disable_scripts integer not null,
16 disable_collisions integer not null,
17 disable_physics integer not null,
18 terrain_texture_1 char(36) not null,
19 terrain_texture_2 char(36) not null,
20 terrain_texture_3 char(36) not null,
21 terrain_texture_4 char(36) not null,
22 elevation_1_nw float not null,
23 elevation_2_nw float not null,
24 elevation_1_ne float not null,
25 elevation_2_ne float not null,
26 elevation_1_se float not null,
27 elevation_2_se float not null,
28 elevation_1_sw float not null,
29 elevation_2_sw float not null,
30 water_height float not null,
31 terrain_raise_limit float not null,
32 terrain_lower_limit float not null,
33 use_estate_sun integer not null,
34 fixed_sun integer not null,
35 sun_position float not null,
36 covenant char(36));
37
38COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
new file mode 100644
index 0000000..03142af
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
@@ -0,0 +1,6 @@
1BEGIN;
2
3ALTER TABLE users add customType varchar(32) not null default '';
4ALTER TABLE users add partner char(36) not null default '00000000-0000-0000-0000-000000000000';
5
6COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
new file mode 100644
index 0000000..1f6d1bd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3delete from regionsettings;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
new file mode 100644
index 0000000..e45c09a
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3CREATE TABLE `avatarattachments` (`UUID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `attachpoint` int(11) NOT NULL DEFAULT 0, `item` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `asset` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000');
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
new file mode 100644
index 0000000..94ed818
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
@@ -0,0 +1,102 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE estate_groups (
4 EstateID int(10) NOT NULL,
5 uuid char(36) NOT NULL
6);
7
8CREATE TABLE estate_managers (
9 EstateID int(10) NOT NULL,
10 uuid char(36) NOT NULL
11);
12
13CREATE TABLE estate_map (
14 RegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000',
15 EstateID int(11) NOT NULL
16);
17
18CREATE TABLE estate_settings (
19 EstateID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
20 EstateName varchar(64) default NULL,
21 AbuseEmailToEstateOwner tinyint(4) NOT NULL,
22 DenyAnonymous tinyint(4) NOT NULL,
23 ResetHomeOnTeleport tinyint(4) NOT NULL,
24 FixedSun tinyint(4) NOT NULL,
25 DenyTransacted tinyint(4) NOT NULL,
26 BlockDwell tinyint(4) NOT NULL,
27 DenyIdentified tinyint(4) NOT NULL,
28 AllowVoice tinyint(4) NOT NULL,
29 UseGlobalTime tinyint(4) NOT NULL,
30 PricePerMeter int(11) NOT NULL,
31 TaxFree tinyint(4) NOT NULL,
32 AllowDirectTeleport tinyint(4) NOT NULL,
33 RedirectGridX int(11) NOT NULL,
34 RedirectGridY int(11) NOT NULL,
35 ParentEstateID int(10) NOT NULL,
36 SunPosition double NOT NULL,
37 EstateSkipScripts tinyint(4) NOT NULL,
38 BillableFactor float NOT NULL,
39 PublicAccess tinyint(4) NOT NULL
40);
41insert into estate_settings (EstateID,EstateName,AbuseEmailToEstateOwner,DenyAnonymous,ResetHomeOnTeleport,FixedSun,DenyTransacted,BlockDwell,DenyIdentified,AllowVoice,UseGlobalTime,PricePerMeter,TaxFree,AllowDirectTeleport,RedirectGridX,RedirectGridY,ParentEstateID,SunPosition,PublicAccess,EstateSkipScripts,BillableFactor) values ( 99, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
42delete from estate_settings;
43CREATE TABLE estate_users (
44 EstateID int(10) NOT NULL,
45 uuid char(36) NOT NULL
46);
47
48CREATE TABLE estateban (
49 EstateID int(10) NOT NULL,
50 bannedUUID varchar(36) NOT NULL,
51 bannedIp varchar(16) NOT NULL,
52 bannedIpHostMask varchar(16) NOT NULL,
53 bannedNameMask varchar(64) default NULL
54);
55
56drop table regionsettings;
57CREATE TABLE regionsettings (
58 regionUUID char(36) NOT NULL,
59 block_terraform int(11) NOT NULL,
60 block_fly int(11) NOT NULL,
61 allow_damage int(11) NOT NULL,
62 restrict_pushing int(11) NOT NULL,
63 allow_land_resell int(11) NOT NULL,
64 allow_land_join_divide int(11) NOT NULL,
65 block_show_in_search int(11) NOT NULL,
66 agent_limit int(11) NOT NULL,
67 object_bonus float NOT NULL,
68 maturity int(11) NOT NULL,
69 disable_scripts int(11) NOT NULL,
70 disable_collisions int(11) NOT NULL,
71 disable_physics int(11) NOT NULL,
72 terrain_texture_1 char(36) NOT NULL,
73 terrain_texture_2 char(36) NOT NULL,
74 terrain_texture_3 char(36) NOT NULL,
75 terrain_texture_4 char(36) NOT NULL,
76 elevation_1_nw float NOT NULL,
77 elevation_2_nw float NOT NULL,
78 elevation_1_ne float NOT NULL,
79 elevation_2_ne float NOT NULL,
80 elevation_1_se float NOT NULL,
81 elevation_2_se float NOT NULL,
82 elevation_1_sw float NOT NULL,
83 elevation_2_sw float NOT NULL,
84 water_height float NOT NULL,
85 terrain_raise_limit float NOT NULL,
86 terrain_lower_limit float NOT NULL,
87 use_estate_sun int(11) NOT NULL,
88 fixed_sun int(11) NOT NULL,
89 sun_position float NOT NULL,
90 covenant char(36) default NULL,
91 Sandbox tinyint(4) NOT NULL,
92 PRIMARY KEY (regionUUID)
93);
94
95CREATE INDEX estate_ban_estate_id on estateban(EstateID);
96CREATE INDEX estate_groups_estate_id on estate_groups(EstateID);
97CREATE INDEX estate_managers_estate_id on estate_managers(EstateID);
98CREATE INDEX estate_map_estate_id on estate_map(EstateID);
99CREATE UNIQUE INDEX estate_map_region_id on estate_map(RegionID);
100CREATE INDEX estate_users_estate_id on estate_users(EstateID);
101
102COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
new file mode 100644
index 0000000..f9454c5
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
@@ -0,0 +1,20 @@
1BEGIN TRANSACTION;
2
3-- usersagents table
4CREATE TABLE IF NOT EXISTS useragents(
5 UUID varchar(255) primary key,
6 agentIP varchar(255),
7 agentPort integer,
8 agentOnline boolean,
9 sessionID varchar(255),
10 secureSessionID varchar(255),
11 regionID varchar(255),
12 loginTime integer,
13 logoutTime integer,
14 currentRegion varchar(255),
15 currentHandle varchar(255),
16 currentPosX float,
17 currentPosY float,
18 currentPosZ float);
19
20COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
new file mode 100644
index 0000000..1c813a0
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
@@ -0,0 +1,8 @@
1begin;
2
3alter table estate_settings add column AbuseEmail varchar(255) not null default '';
4
5alter table estate_settings add column EstateOwner varchar(36) not null default '';
6
7commit;
8
diff --git a/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
new file mode 100644
index 0000000..8b0cd28
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
@@ -0,0 +1,7 @@
1BEGIN TRANSACTION;
2
3ALTER TABLE useragents add currentLookAtX float not null default 128;
4ALTER TABLE useragents add currentLookAtY float not null default 128;
5ALTER TABLE useragents add currentLookAtZ float not null default 70;
6
7COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
new file mode 100644
index 0000000..28bfbf5
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
@@ -0,0 +1,6 @@
1begin;
2
3alter table estate_settings add column DenyMinors tinyint not null default 0;
4
5commit;
6
diff --git a/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
new file mode 100644
index 0000000..97da818
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
@@ -0,0 +1,5 @@
1BEGIN TRANSACTION;
2
3ALTER TABLE users add email varchar(250);
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
new file mode 100644
index 0000000..1f40548
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
@@ -0,0 +1,8 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN ColorR integer not null default 0;
4ALTER TABLE prims ADD COLUMN ColorG integer not null default 0;
5ALTER TABLE prims ADD COLUMN ColorB integer not null default 0;
6ALTER TABLE prims ADD COLUMN ColorA integer not null default 0;
7
8COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
new file mode 100644
index 0000000..8ab03ef
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
@@ -0,0 +1,11 @@
1BEGIN;
2
3update users
4 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
5 where UUID not like '%-%';
6
7update useragents
8 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
9 where UUID not like '%-%';
10
11COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
new file mode 100644
index 0000000..b91ccf0
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN ClickAction INTEGER NOT NULL default 0;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
new file mode 100644
index 0000000..5f956da
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
@@ -0,0 +1,37 @@
1BEGIN TRANSACTION;
2
3CREATE TABLE IF NOT EXISTS avatarappearance(
4 Owner varchar(36) NOT NULL primary key,
5 BodyItem varchar(36) DEFAULT NULL,
6 BodyAsset varchar(36) DEFAULT NULL,
7 SkinItem varchar(36) DEFAULT NULL,
8 SkinAsset varchar(36) DEFAULT NULL,
9 HairItem varchar(36) DEFAULT NULL,
10 HairAsset varchar(36) DEFAULT NULL,
11 EyesItem varchar(36) DEFAULT NULL,
12 EyesAsset varchar(36) DEFAULT NULL,
13 ShirtItem varchar(36) DEFAULT NULL,
14 ShirtAsset varchar(36) DEFAULT NULL,
15 PantsItem varchar(36) DEFAULT NULL,
16 PantsAsset varchar(36) DEFAULT NULL,
17 ShoesItem varchar(36) DEFAULT NULL,
18 ShoesAsset varchar(36) DEFAULT NULL,
19 SocksItem varchar(36) DEFAULT NULL,
20 SocksAsset varchar(36) DEFAULT NULL,
21 JacketItem varchar(36) DEFAULT NULL,
22 JacketAsset varchar(36) DEFAULT NULL,
23 GlovesItem varchar(36) DEFAULT NULL,
24 GlovesAsset varchar(36) DEFAULT NULL,
25 UnderShirtItem varchar(36) DEFAULT NULL,
26 UnderShirtAsset varchar(36) DEFAULT NULL,
27 UnderPantsItem varchar(36) DEFAULT NULL,
28 UnderPantsAsset varchar(36) DEFAULT NULL,
29 SkirtItem varchar(36) DEFAULT NULL,
30 SkirtAsset varchar(36) DEFAULT NULL,
31 Texture blob,
32 VisualParams blob,
33 Serial int DEFAULT NULL,
34 AvatarHeight float DEFAULT NULL
35);
36
37COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
new file mode 100644
index 0000000..42bef89
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
@@ -0,0 +1,28 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN PayPrice INTEGER NOT NULL default 0;
4ALTER TABLE prims ADD COLUMN PayButton1 INTEGER NOT NULL default 0;
5ALTER TABLE prims ADD COLUMN PayButton2 INTEGER NOT NULL default 0;
6ALTER TABLE prims ADD COLUMN PayButton3 INTEGER NOT NULL default 0;
7ALTER TABLE prims ADD COLUMN PayButton4 INTEGER NOT NULL default 0;
8ALTER TABLE prims ADD COLUMN LoopedSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
9ALTER TABLE prims ADD COLUMN LoopedSoundGain float NOT NULL default 0;
10ALTER TABLE prims ADD COLUMN TextureAnimation string;
11ALTER TABLE prims ADD COLUMN ParticleSystem string;
12ALTER TABLE prims ADD COLUMN OmegaX float NOT NULL default 0;
13ALTER TABLE prims ADD COLUMN OmegaY float NOT NULL default 0;
14ALTER TABLE prims ADD COLUMN OmegaZ float NOT NULL default 0;
15ALTER TABLE prims ADD COLUMN CameraEyeOffsetX float NOT NULL default 0;
16ALTER TABLE prims ADD COLUMN CameraEyeOffsetY float NOT NULL default 0;
17ALTER TABLE prims ADD COLUMN CameraEyeOffsetZ float NOT NULL default 0;
18ALTER TABLE prims ADD COLUMN CameraAtOffsetX float NOT NULL default 0;
19ALTER TABLE prims ADD COLUMN CameraAtOffsetY float NOT NULL default 0;
20ALTER TABLE prims ADD COLUMN CameraAtOffsetZ float NOT NULL default 0;
21ALTER TABLE prims ADD COLUMN ForceMouselook string NOT NULL default 0;
22ALTER TABLE prims ADD COLUMN ScriptAccessPin INTEGER NOT NULL default 0;
23ALTER TABLE prims ADD COLUMN AllowedDrop INTEGER NOT NULL default 0;
24ALTER TABLE prims ADD COLUMN DieAtEdge string NOT NULL default 0;
25ALTER TABLE prims ADD COLUMN SalePrice INTEGER NOT NULL default 0;
26ALTER TABLE prims ADD COLUMN SaleType string NOT NULL default 0;
27
28COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
new file mode 100644
index 0000000..d952b78
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN Material INTEGER NOT NULL default 3;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
new file mode 100644
index 0000000..11529cd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
@@ -0,0 +1,6 @@
1BEGIN;
2
3ALTER TABLE land ADD COLUMN OtherCleanTime INTEGER NOT NULL default 0;
4ALTER TABLE land ADD COLUMN Dwell INTEGER NOT NULL default 0;
5
6COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
new file mode 100644
index 0000000..c59b27e
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
@@ -0,0 +1,8 @@
1begin;
2
3ALTER TABLE regionsettings ADD COLUMN sunvectorx double NOT NULL default 0;
4ALTER TABLE regionsettings ADD COLUMN sunvectory double NOT NULL default 0;
5ALTER TABLE regionsettings ADD COLUMN sunvectorz double NOT NULL default 0;
6
7commit;
8
diff --git a/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
new file mode 100644
index 0000000..c43f356
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
@@ -0,0 +1,6 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN CollisionSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
4ALTER TABLE prims ADD COLUMN CollisionSoundVolume float NOT NULL default 0;
5
6COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
new file mode 100644
index 0000000..52f160c
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
@@ -0,0 +1,5 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN VolumeDetect INTEGER NOT NULL DEFAULT 0;
4
5COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
new file mode 100644
index 0000000..6c6b7b5
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
@@ -0,0 +1,8 @@
1BEGIN;
2CREATE TEMPORARY TABLE prims_backup(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect);
3INSERT INTO prims_backup SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims;
4DROP TABLE prims;
5CREATE TABLE prims(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect);
6INSERT INTO prims SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims_backup;
7DROP TABLE prims_backup;
8COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
new file mode 100644
index 0000000..6a390c2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
@@ -0,0 +1,79 @@
1BEGIN;
2
3update terrain
4 set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
5 where RegionUUID not like '%-%';
6
7
8update landaccesslist
9 set LandUUID = substr(LandUUID, 1, 8) || "-" || substr(LandUUID, 9, 4) || "-" || substr(LandUUID, 13, 4) || "-" || substr(LandUUID, 17, 4) || "-" || substr(LandUUID, 21, 12)
10 where LandUUID not like '%-%';
11
12update landaccesslist
13 set AccessUUID = substr(AccessUUID, 1, 8) || "-" || substr(AccessUUID, 9, 4) || "-" || substr(AccessUUID, 13, 4) || "-" || substr(AccessUUID, 17, 4) || "-" || substr(AccessUUID, 21, 12)
14 where AccessUUID not like '%-%';
15
16
17update prims
18 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
19 where UUID not like '%-%';
20
21update prims
22 set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
23 where RegionUUID not like '%-%';
24
25update prims
26 set SceneGroupID = substr(SceneGroupID, 1, 8) || "-" || substr(SceneGroupID, 9, 4) || "-" || substr(SceneGroupID, 13, 4) || "-" || substr(SceneGroupID, 17, 4) || "-" || substr(SceneGroupID, 21, 12)
27 where SceneGroupID not like '%-%';
28
29update prims
30 set CreatorID = substr(CreatorID, 1, 8) || "-" || substr(CreatorID, 9, 4) || "-" || substr(CreatorID, 13, 4) || "-" || substr(CreatorID, 17, 4) || "-" || substr(CreatorID, 21, 12)
31 where CreatorID not like '%-%';
32
33update prims
34 set OwnerID = substr(OwnerID, 1, 8) || "-" || substr(OwnerID, 9, 4) || "-" || substr(OwnerID, 13, 4) || "-" || substr(OwnerID, 17, 4) || "-" || substr(OwnerID, 21, 12)
35 where OwnerID not like '%-%';
36
37update prims
38 set GroupID = substr(GroupID, 1, 8) || "-" || substr(GroupID, 9, 4) || "-" || substr(GroupID, 13, 4) || "-" || substr(GroupID, 17, 4) || "-" || substr(GroupID, 21, 12)
39 where GroupID not like '%-%';
40
41update prims
42 set LastOwnerID = substr(LastOwnerID, 1, 8) || "-" || substr(LastOwnerID, 9, 4) || "-" || substr(LastOwnerID, 13, 4) || "-" || substr(LastOwnerID, 17, 4) || "-" || substr(LastOwnerID, 21, 12)
43 where LastOwnerID not like '%-%';
44
45
46update primshapes
47 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
48 where UUID not like '%-%';
49
50
51update land
52 set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
53 where UUID not like '%-%';
54
55update land
56 set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
57 where RegionUUID not like '%-%';
58
59update land
60 set OwnerUUID = substr(OwnerUUID, 1, 8) || "-" || substr(OwnerUUID, 9, 4) || "-" || substr(OwnerUUID, 13, 4) || "-" || substr(OwnerUUID, 17, 4) || "-" || substr(OwnerUUID, 21, 12)
61 where OwnerUUID not like '%-%';
62
63update land
64 set GroupUUID = substr(GroupUUID, 1, 8) || "-" || substr(GroupUUID, 9, 4) || "-" || substr(GroupUUID, 13, 4) || "-" || substr(GroupUUID, 17, 4) || "-" || substr(GroupUUID, 21, 12)
65 where GroupUUID not like '%-%';
66
67update land
68 set MediaTextureUUID = substr(MediaTextureUUID, 1, 8) || "-" || substr(MediaTextureUUID, 9, 4) || "-" || substr(MediaTextureUUID, 13, 4) || "-" || substr(MediaTextureUUID, 17, 4) || "-" || substr(MediaTextureUUID, 21, 12)
69 where MediaTextureUUID not like '%-%';
70
71update land
72 set SnapshotUUID = substr(SnapshotUUID, 1, 8) || "-" || substr(SnapshotUUID, 9, 4) || "-" || substr(SnapshotUUID, 13, 4) || "-" || substr(SnapshotUUID, 17, 4) || "-" || substr(SnapshotUUID, 21, 12)
73 where SnapshotUUID not like '%-%';
74
75update land
76 set AuthbuyerID = substr(AuthbuyerID, 1, 8) || "-" || substr(AuthbuyerID, 9, 4) || "-" || substr(AuthbuyerID, 13, 4) || "-" || substr(AuthbuyerID, 17, 4) || "-" || substr(AuthbuyerID, 21, 12)
77 where AuthbuyerID not like '%-%';
78
79COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml b/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
new file mode 100644
index 0000000..e6764fa
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
@@ -0,0 +1,20 @@
1<Addin id="OpenSim.Data.SQLite" version="0.1">
2 <Runtime>
3 <Import assembly="OpenSim.Data.SQLite.dll"/>
4 </Runtime>
5 <Dependencies>
6 <Addin id="OpenSim.Data" version="0.5" />
7 </Dependencies>
8 <Extension path = "/OpenSim/GridData">
9 <Plugin id="SQLiteGridData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteGridData" />
10 </Extension>
11 <Extension path = "/OpenSim/AssetData">
12 <Plugin id="SQLiteAssetData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteAssetData" />
13 </Extension>
14 <Extension path = "/OpenSim/InventoryData">
15 <Plugin id="SQLiteInventoryData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteInventoryStore" />
16 </Extension>
17 <Extension path = "/OpenSim/UserData">
18 <Plugin id="SQLiteUserData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteUserData" />
19 </Extension>
20</Addin>
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
new file mode 100644
index 0000000..9b34a21
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
@@ -0,0 +1,343 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Data;
30using System.Reflection;
31using System.Collections.Generic;
32using log4net;
33using Mono.Data.Sqlite;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37namespace OpenSim.Data.SQLiteNG
38{
39 /// <summary>
40 /// An asset storage interface for the SQLite database system
41 /// </summary>
42 public class SQLiteAssetData : AssetDataBase
43 {
44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private const string SelectAssetSQL = "select * from assets where UUID=:UUID";
47 private const string SelectAssetMetadataSQL = "select Name, Description, Type, Temporary, UUID from assets limit :start, :count";
48 private const string DeleteAssetSQL = "delete from assets where UUID=:UUID";
49 private const string InsertAssetSQL = "insert into assets(UUID, Name, Description, Type, Local, Temporary, Data) values(:UUID, :Name, :Description, :Type, :Local, :Temporary, :Data)";
50 private const string UpdateAssetSQL = "update assets set Name=:Name, Description=:Description, Type=:Type, Local=:Local, Temporary=:Temporary, Data=:Data where UUID=:UUID";
51 private const string assetSelect = "select * from assets";
52
53 private SqliteConnection m_conn;
54
55 override public void Dispose()
56 {
57 if (m_conn != null)
58 {
59 m_conn.Close();
60 m_conn = null;
61 }
62 }
63
64 /// <summary>
65 /// <list type="bullet">
66 /// <item>Initialises AssetData interface</item>
67 /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
68 /// <item>use default URI if connect string is empty.</item>
69 /// </list>
70 /// </summary>
71 /// <param name="dbconnect">connect string</param>
72 override public void Initialise(string dbconnect)
73 {
74 if (dbconnect == string.Empty)
75 {
76 dbconnect = "URI=file:Asset.db,version=3";
77 }
78 m_conn = new SqliteConnection(dbconnect);
79 m_conn.Open();
80
81 Assembly assem = GetType().Assembly;
82 Migration m = new Migration(m_conn, assem, "AssetStore");
83 m.Update();
84
85 return;
86 }
87
88 /// <summary>
89 /// Fetch Asset
90 /// </summary>
91 /// <param name="uuid">UUID of ... ?</param>
92 /// <returns>Asset base</returns>
93 override public AssetBase GetAsset(UUID uuid)
94 {
95 lock (this)
96 {
97 using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
98 {
99 cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
100 using (IDataReader reader = cmd.ExecuteReader())
101 {
102 if (reader.Read())
103 {
104 AssetBase asset = buildAsset(reader);
105 reader.Close();
106 return asset;
107 }
108 else
109 {
110 reader.Close();
111 return null;
112 }
113 }
114 }
115 }
116 }
117
118 /// <summary>
119 /// Create an asset
120 /// </summary>
121 /// <param name="asset">Asset Base</param>
122 override public void StoreAsset(AssetBase asset)
123 {
124 //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
125 if (ExistsAsset(asset.FullID))
126 {
127 //LogAssetLoad(asset);
128
129 lock (this)
130 {
131 using (SqliteCommand cmd = new SqliteCommand(UpdateAssetSQL, m_conn))
132 {
133 cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString()));
134 cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name));
135 cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description));
136 cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type));
137 cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
138 cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
139 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
140
141 cmd.ExecuteNonQuery();
142 }
143 }
144 }
145 else
146 {
147 lock (this)
148 {
149 using (SqliteCommand cmd = new SqliteCommand(InsertAssetSQL, m_conn))
150 {
151 cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString()));
152 cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name));
153 cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description));
154 cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type));
155 cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
156 cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
157 cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
158
159 cmd.ExecuteNonQuery();
160 }
161 }
162 }
163 }
164
165// /// <summary>
166// /// Some... logging functionnality
167// /// </summary>
168// /// <param name="asset"></param>
169// private static void LogAssetLoad(AssetBase asset)
170// {
171// string temporary = asset.Temporary ? "Temporary" : "Stored";
172// string local = asset.Local ? "Local" : "Remote";
173//
174// int assetLength = (asset.Data != null) ? asset.Data.Length : 0;
175//
176// m_log.Debug("[ASSET DB]: " +
177// string.Format("Loaded {5} {4} Asset: [{0}][{3}] \"{1}\":{2} ({6} bytes)",
178// asset.FullID, asset.Name, asset.Description, asset.Type,
179// temporary, local, assetLength));
180// }
181
182 /// <summary>
183 /// Check if an asset exist in database
184 /// </summary>
185 /// <param name="uuid">The asset UUID</param>
186 /// <returns>True if exist, or false.</returns>
187 override public bool ExistsAsset(UUID uuid)
188 {
189 lock (this) {
190 using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
191 {
192 cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
193 using (IDataReader reader = cmd.ExecuteReader())
194 {
195 if (reader.Read())
196 {
197 reader.Close();
198 return true;
199 }
200 else
201 {
202 reader.Close();
203 return false;
204 }
205 }
206 }
207 }
208 }
209
210 /// <summary>
211 /// Delete an asset from database
212 /// </summary>
213 /// <param name="uuid"></param>
214 public void DeleteAsset(UUID uuid)
215 {
216 using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn))
217 {
218 cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
219
220 cmd.ExecuteNonQuery();
221 }
222 }
223
224 /// <summary>
225 ///
226 /// </summary>
227 /// <param name="row"></param>
228 /// <returns></returns>
229 private static AssetBase buildAsset(IDataReader row)
230 {
231 // TODO: this doesn't work yet because something more
232 // interesting has to be done to actually get these values
233 // back out. Not enough time to figure it out yet.
234 AssetBase asset = new AssetBase(
235 new UUID((String)row["UUID"]),
236 (String)row["Name"],
237 Convert.ToSByte(row["Type"]),
238 UUID.Zero.ToString()
239 );
240
241 asset.Description = (String) row["Description"];
242 asset.Local = Convert.ToBoolean(row["Local"]);
243 asset.Temporary = Convert.ToBoolean(row["Temporary"]);
244 asset.Data = (byte[]) row["Data"];
245 return asset;
246 }
247
248 private static AssetMetadata buildAssetMetadata(IDataReader row)
249 {
250 AssetMetadata metadata = new AssetMetadata();
251
252 metadata.FullID = new UUID((string) row["UUID"]);
253 metadata.Name = (string) row["Name"];
254 metadata.Description = (string) row["Description"];
255 metadata.Type = Convert.ToSByte(row["Type"]);
256 metadata.Temporary = Convert.ToBoolean(row["Temporary"]); // Not sure if this is correct.
257
258 // Current SHA1s are not stored/computed.
259 metadata.SHA1 = new byte[] {};
260
261 return metadata;
262 }
263
264 /// <summary>
265 /// Returns a list of AssetMetadata objects. The list is a subset of
266 /// the entire data set offset by <paramref name="start" /> containing
267 /// <paramref name="count" /> elements.
268 /// </summary>
269 /// <param name="start">The number of results to discard from the total data set.</param>
270 /// <param name="count">The number of rows the returned list should contain.</param>
271 /// <returns>A list of AssetMetadata objects.</returns>
272 public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
273 {
274 List<AssetMetadata> retList = new List<AssetMetadata>(count);
275
276 lock (this)
277 {
278 using (SqliteCommand cmd = new SqliteCommand(SelectAssetMetadataSQL, m_conn))
279 {
280 cmd.Parameters.Add(new SqliteParameter(":start", start));
281 cmd.Parameters.Add(new SqliteParameter(":count", count));
282
283 using (IDataReader reader = cmd.ExecuteReader())
284 {
285 while (reader.Read())
286 {
287 AssetMetadata metadata = buildAssetMetadata(reader);
288 retList.Add(metadata);
289 }
290 }
291 }
292 }
293
294 return retList;
295 }
296
297 /***********************************************************************
298 *
299 * Database Binding functions
300 *
301 * These will be db specific due to typing, and minor differences
302 * in databases.
303 *
304 **********************************************************************/
305
306 #region IPlugin interface
307
308 /// <summary>
309 ///
310 /// </summary>
311 override public string Version
312 {
313 get
314 {
315 Module module = GetType().Module;
316 // string dllName = module.Assembly.ManifestModule.Name;
317 Version dllVersion = module.Assembly.GetName().Version;
318
319 return
320 string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
321 dllVersion.Revision);
322 }
323 }
324
325 /// <summary>
326 /// Initialise the AssetData interface using default URI
327 /// </summary>
328 override public void Initialise()
329 {
330 Initialise("URI=file:Asset.db,version=3");
331 }
332
333 /// <summary>
334 /// Name of this DB provider
335 /// </summary>
336 override public string Name
337 {
338 get { return "SQLite Asset storage engine"; }
339 }
340
341 #endregion
342 }
343}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
new file mode 100644
index 0000000..4a5dc2e
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
@@ -0,0 +1,257 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.Sqlite;
35
36namespace OpenSim.Data.SQLiteNG
37{
38 public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData
39 {
40 private string m_Realm;
41 private List<string> m_ColumnNames;
42 private int m_LastExpire;
43 private string m_connectionString;
44
45 protected static SqliteConnection m_Connection;
46 private static bool m_initialized = false;
47
48 public SQLiteAuthenticationData(string connectionString, string realm)
49 : base(connectionString)
50 {
51 m_Realm = realm;
52 m_connectionString = connectionString;
53
54 if (!m_initialized)
55 {
56 m_Connection = new SqliteConnection(connectionString);
57 m_Connection.Open();
58
59 Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore");
60 m.Update();
61
62 m_initialized = true;
63 }
64 }
65
66 public AuthenticationData Get(UUID principalID)
67 {
68 AuthenticationData ret = new AuthenticationData();
69 ret.Data = new Dictionary<string, object>();
70
71 SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID");
72 cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
73
74 IDataReader result = ExecuteReader(cmd, m_Connection);
75
76 try
77 {
78 if (result.Read())
79 {
80 ret.PrincipalID = principalID;
81
82 if (m_ColumnNames == null)
83 {
84 m_ColumnNames = new List<string>();
85
86 DataTable schemaTable = result.GetSchemaTable();
87 foreach (DataRow row in schemaTable.Rows)
88 m_ColumnNames.Add(row["ColumnName"].ToString());
89 }
90
91 foreach (string s in m_ColumnNames)
92 {
93 if (s == "UUID")
94 continue;
95
96 ret.Data[s] = result[s].ToString();
97 }
98
99 return ret;
100 }
101 else
102 {
103 return null;
104 }
105 }
106 catch
107 {
108 }
109 finally
110 {
111 //CloseCommand(cmd);
112 }
113
114 return null;
115 }
116
117 public bool Store(AuthenticationData data)
118 {
119 if (data.Data.ContainsKey("UUID"))
120 data.Data.Remove("UUID");
121
122 string[] fields = new List<string>(data.Data.Keys).ToArray();
123 string[] values = new string[data.Data.Count];
124 int i = 0;
125 foreach (object o in data.Data.Values)
126 values[i++] = o.ToString();
127
128 SqliteCommand cmd = new SqliteCommand();
129
130 if (Get(data.PrincipalID) != null)
131 {
132
133
134 string update = "update `" + m_Realm + "` set ";
135 bool first = true;
136 foreach (string field in fields)
137 {
138 if (!first)
139 update += ", ";
140 update += "`" + field + "` = :" + field;
141 cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
142
143 first = false;
144 }
145
146 update += " where UUID = :UUID";
147 cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
148
149 cmd.CommandText = update;
150 try
151 {
152 if (ExecuteNonQuery(cmd, m_Connection) < 1)
153 {
154 //CloseCommand(cmd);
155 return false;
156 }
157 }
158 catch (Exception e)
159 {
160 Console.WriteLine(e.ToString());
161 //CloseCommand(cmd);
162 return false;
163 }
164 }
165
166 else
167 {
168 string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
169 String.Join("`, `", fields) +
170 "`) values (:UUID, :" + String.Join(", :", fields) + ")";
171
172 cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
173 foreach (string field in fields)
174 cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
175
176 cmd.CommandText = insert;
177
178 try
179 {
180 if (ExecuteNonQuery(cmd, m_Connection) < 1)
181 {
182 //CloseCommand(cmd);
183 return false;
184 }
185 }
186 catch (Exception e)
187 {
188 Console.WriteLine(e.ToString());
189 //CloseCommand(cmd);
190 return false;
191 }
192 }
193
194 //CloseCommand(cmd);
195
196 return true;
197 }
198
199 public bool SetDataItem(UUID principalID, string item, string value)
200 {
201 SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
202 "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'");
203
204 if (ExecuteNonQuery(cmd, m_Connection) > 0)
205 return true;
206
207 return false;
208 }
209
210 public bool SetToken(UUID principalID, string token, int lifetime)
211 {
212 if (System.Environment.TickCount - m_LastExpire > 30000)
213 DoExpire();
214
215 SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() +
216 "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))");
217
218 if (ExecuteNonQuery(cmd, m_Connection) > 0)
219 {
220 cmd.Dispose();
221 return true;
222 }
223
224 cmd.Dispose();
225 return false;
226 }
227
228 public bool CheckToken(UUID principalID, string token, int lifetime)
229 {
230 if (System.Environment.TickCount - m_LastExpire > 30000)
231 DoExpire();
232
233 SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() +
234 " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')");
235
236 if (ExecuteNonQuery(cmd, m_Connection) > 0)
237 {
238 cmd.Dispose();
239 return true;
240 }
241
242 cmd.Dispose();
243
244 return false;
245 }
246
247 private void DoExpire()
248 {
249 SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')");
250 ExecuteNonQuery(cmd, m_Connection);
251
252 cmd.Dispose();
253
254 m_LastExpire = System.Environment.TickCount;
255 }
256 }
257}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
new file mode 100644
index 0000000..d0fd49c
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
@@ -0,0 +1,74 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using Mono.Data.Sqlite;
37
38namespace OpenSim.Data.SQLiteNG
39{
40 /// <summary>
41 /// A SQLite Interface for Avatar Data
42 /// </summary>
43 public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>,
44 IAvatarData
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public SQLiteAvatarData(string connectionString, string realm) :
49 base(connectionString, realm, "Avatar")
50 {
51 }
52
53 public bool Delete(UUID principalID, string name)
54 {
55 SqliteCommand cmd = new SqliteCommand();
56
57 cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm);
58 cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
59 cmd.Parameters.AddWithValue(":Name", name);
60
61 try
62 {
63 if (ExecuteNonQuery(cmd, m_Connection) > 0)
64 return true;
65
66 return false;
67 }
68 finally
69 {
70 //CloseCommand(cmd);
71 }
72 }
73 }
74}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
new file mode 100644
index 0000000..2e2d717
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
@@ -0,0 +1,387 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using Mono.Data.Sqlite;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37
38namespace OpenSim.Data.SQLiteNG
39{
40 public class SQLiteEstateStore : IEstateDataStore
41 {
42 private static readonly ILog m_log =
43 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 private SqliteConnection m_connection;
46 private string m_connectionString;
47
48 private FieldInfo[] m_Fields;
49 private Dictionary<string, FieldInfo> m_FieldMap =
50 new Dictionary<string, FieldInfo>();
51
52 public void Initialise(string connectionString)
53 {
54 m_connectionString = connectionString;
55
56 m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString);
57
58 m_connection = new SqliteConnection(m_connectionString);
59 m_connection.Open();
60
61 Assembly assem = GetType().Assembly;
62 Migration m = new Migration(m_connection, assem, "EstateStore");
63 m.Update();
64
65 //m_connection.Close();
66 // m_connection.Open();
67
68 Type t = typeof(EstateSettings);
69 m_Fields = t.GetFields(BindingFlags.NonPublic |
70 BindingFlags.Instance |
71 BindingFlags.DeclaredOnly);
72
73 foreach (FieldInfo f in m_Fields)
74 if (f.Name.Substring(0, 2) == "m_")
75 m_FieldMap[f.Name.Substring(2)] = f;
76 }
77
78 private string[] FieldList
79 {
80 get { return new List<string>(m_FieldMap.Keys).ToArray(); }
81 }
82
83 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
84 {
85 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";
86
87 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
88
89 cmd.CommandText = sql;
90 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
91
92 return DoLoad(cmd, regionID, create);
93 }
94
95 private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create)
96 {
97 EstateSettings es = new EstateSettings();
98 es.OnSave += StoreEstateSettings;
99
100 IDataReader r = cmd.ExecuteReader();
101
102 if (r.Read())
103 {
104 foreach (string name in FieldList)
105 {
106 if (m_FieldMap[name].GetValue(es) is bool)
107 {
108 int v = Convert.ToInt32(r[name]);
109 if (v != 0)
110 m_FieldMap[name].SetValue(es, true);
111 else
112 m_FieldMap[name].SetValue(es, false);
113 }
114 else if (m_FieldMap[name].GetValue(es) is UUID)
115 {
116 UUID uuid = UUID.Zero;
117
118 UUID.TryParse(r[name].ToString(), out uuid);
119 m_FieldMap[name].SetValue(es, uuid);
120 }
121 else
122 {
123 m_FieldMap[name].SetValue(es, Convert.ChangeType(r[name], m_FieldMap[name].FieldType));
124 }
125 }
126 r.Close();
127 }
128 else if (create)
129 {
130 r.Close();
131
132 List<string> names = new List<string>(FieldList);
133
134 names.Remove("EstateID");
135
136 string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
137
138 cmd.CommandText = sql;
139 cmd.Parameters.Clear();
140
141 foreach (string name in FieldList)
142 {
143 if (m_FieldMap[name].GetValue(es) is bool)
144 {
145 if ((bool)m_FieldMap[name].GetValue(es))
146 cmd.Parameters.AddWithValue(":"+name, "1");
147 else
148 cmd.Parameters.AddWithValue(":"+name, "0");
149 }
150 else
151 {
152 cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
153 }
154 }
155
156 cmd.ExecuteNonQuery();
157
158 cmd.CommandText = "select LAST_INSERT_ROWID() as id";
159 cmd.Parameters.Clear();
160
161 r = cmd.ExecuteReader();
162
163 r.Read();
164
165 es.EstateID = Convert.ToUInt32(r["id"]);
166
167 r.Close();
168
169 cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
170 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
171 cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
172
173 // This will throw on dupe key
174 try
175 {
176 cmd.ExecuteNonQuery();
177 }
178 catch (Exception)
179 {
180 }
181
182 es.Save();
183 }
184
185 LoadBanList(es);
186
187 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
188 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
189 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
190 return es;
191 }
192
193 public void StoreEstateSettings(EstateSettings es)
194 {
195 List<string> fields = new List<string>(FieldList);
196 fields.Remove("EstateID");
197
198 List<string> terms = new List<string>();
199
200 foreach (string f in fields)
201 terms.Add(f+" = :"+f);
202
203 string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID";
204
205 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
206
207 cmd.CommandText = sql;
208
209 foreach (string name in FieldList)
210 {
211 if (m_FieldMap[name].GetValue(es) is bool)
212 {
213 if ((bool)m_FieldMap[name].GetValue(es))
214 cmd.Parameters.AddWithValue(":"+name, "1");
215 else
216 cmd.Parameters.AddWithValue(":"+name, "0");
217 }
218 else
219 {
220 cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
221 }
222 }
223
224 cmd.ExecuteNonQuery();
225
226 SaveBanList(es);
227 SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
228 SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
229 SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
230 }
231
232 private void LoadBanList(EstateSettings es)
233 {
234 es.ClearBans();
235
236 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
237
238 cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID";
239 cmd.Parameters.AddWithValue(":EstateID", es.EstateID);
240
241 IDataReader r = cmd.ExecuteReader();
242
243 while (r.Read())
244 {
245 EstateBan eb = new EstateBan();
246
247 UUID uuid = new UUID();
248 UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
249
250 eb.BannedUserID = uuid;
251 eb.BannedHostAddress = "0.0.0.0";
252 eb.BannedHostIPMask = "0.0.0.0";
253 es.AddBan(eb);
254 }
255 r.Close();
256 }
257
258 private void SaveBanList(EstateSettings es)
259 {
260 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
261
262 cmd.CommandText = "delete from estateban where EstateID = :EstateID";
263 cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
264
265 cmd.ExecuteNonQuery();
266
267 cmd.Parameters.Clear();
268
269 cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )";
270
271 foreach (EstateBan b in es.EstateBans)
272 {
273 cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
274 cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString());
275
276 cmd.ExecuteNonQuery();
277 cmd.Parameters.Clear();
278 }
279 }
280
281 void SaveUUIDList(uint EstateID, string table, UUID[] data)
282 {
283 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
284
285 cmd.CommandText = "delete from "+table+" where EstateID = :EstateID";
286 cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString());
287
288 cmd.ExecuteNonQuery();
289
290 cmd.Parameters.Clear();
291
292 cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )";
293
294 foreach (UUID uuid in data)
295 {
296 cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString());
297 cmd.Parameters.AddWithValue(":uuid", uuid.ToString());
298
299 cmd.ExecuteNonQuery();
300 cmd.Parameters.Clear();
301 }
302 }
303
304 UUID[] LoadUUIDList(uint EstateID, string table)
305 {
306 List<UUID> uuids = new List<UUID>();
307
308 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
309
310 cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID";
311 cmd.Parameters.AddWithValue(":EstateID", EstateID);
312
313 IDataReader r = cmd.ExecuteReader();
314
315 while (r.Read())
316 {
317 // EstateBan eb = new EstateBan();
318
319 UUID uuid = new UUID();
320 UUID.TryParse(r["uuid"].ToString(), out uuid);
321
322 uuids.Add(uuid);
323 }
324 r.Close();
325
326 return uuids.ToArray();
327 }
328
329 public EstateSettings LoadEstateSettings(int estateID)
330 {
331 string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID :EstateID";
332
333 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
334
335 cmd.CommandText = sql;
336 cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
337
338 return DoLoad(cmd, UUID.Zero, false);
339 }
340
341 public List<int> GetEstates(string search)
342 {
343 List<int> result = new List<int>();
344
345 string sql = "select EstateID from estate_settings where estate_settings.EstateName :EstateName";
346
347 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
348
349 cmd.CommandText = sql;
350 cmd.Parameters.AddWithValue(":EstateName", search);
351
352 IDataReader r = cmd.ExecuteReader();
353
354 while (r.Read())
355 {
356 result.Add(Convert.ToInt32(r["EstateID"]));
357 }
358 r.Close();
359
360 return result;
361 }
362
363 public bool LinkRegion(UUID regionID, int estateID)
364 {
365 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
366
367 cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
368 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
369 cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
370
371 if (cmd.ExecuteNonQuery() == 0)
372 return false;
373
374 return true;
375 }
376
377 public List<UUID> GetRegions(int estateID)
378 {
379 return new List<UUID>();
380 }
381
382 public bool DeleteEstate(int estateID)
383 {
384 return false;
385 }
386 }
387}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs
new file mode 100644
index 0000000..f0ddc59
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.Sqlite;
35
36namespace OpenSim.Data.SQLiteNG
37{
38 /// <summary>
39 /// A database interface class to a user profile storage system
40 /// </summary>
41 public class SQLiteFramework
42 {
43 protected Object m_lockObject = new Object();
44
45 protected SQLiteFramework(string connectionString)
46 {
47 }
48
49 //////////////////////////////////////////////////////////////
50 //
51 // All non queries are funneled through one connection
52 // to increase performance a little
53 //
54 protected int ExecuteNonQuery(SqliteCommand cmd, SqliteConnection connection)
55 {
56 lock (connection)
57 {
58/*
59 SqliteConnection newConnection =
60 (SqliteConnection)((ICloneable)connection).Clone();
61 newConnection.Open();
62
63 cmd.Connection = newConnection;
64*/
65 cmd.Connection = connection;
66 //Console.WriteLine("XXX " + cmd.CommandText);
67
68 return cmd.ExecuteNonQuery();
69 }
70 }
71
72 protected IDataReader ExecuteReader(SqliteCommand cmd, SqliteConnection connection)
73 {
74 lock (connection)
75 {
76 //SqliteConnection newConnection =
77 // (SqliteConnection)((ICloneable)connection).Clone();
78 //newConnection.Open();
79
80 //cmd.Connection = newConnection;
81 cmd.Connection = connection;
82 //Console.WriteLine("XXX " + cmd.CommandText);
83
84 return cmd.ExecuteReader();
85 }
86 }
87
88 protected void CloseCommand(SqliteCommand cmd)
89 {
90 cmd.Connection.Close();
91 cmd.Connection.Dispose();
92 cmd.Dispose();
93 }
94 }
95}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
new file mode 100644
index 0000000..702a1d8
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.Sqlite;
35
36namespace OpenSim.Data.SQLiteNG
37{
38 public class SQLiteFriendsData : SQLiteGenericTableHandler<FriendsData>, IFriendsData
39 {
40 public SQLiteFriendsData(string connectionString, string realm)
41 : base(connectionString, realm, "FriendsStore")
42 {
43 }
44
45 public FriendsData[] GetFriends(UUID userID)
46 {
47 SqliteCommand cmd = new SqliteCommand();
48
49 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = :PrincipalID", m_Realm);
50 cmd.Parameters.AddWithValue(":PrincipalID", userID.ToString());
51
52 return DoQuery(cmd);
53
54 }
55
56 public bool Delete(UUID principalID, string friend)
57 {
58 SqliteCommand cmd = new SqliteCommand();
59
60 cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
61 cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
62 cmd.Parameters.AddWithValue(":Friend", friend);
63
64 ExecuteNonQuery(cmd, cmd.Connection);
65
66 return true;
67 }
68
69 }
70}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
new file mode 100644
index 0000000..632c5bf
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
@@ -0,0 +1,270 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using Mono.Data.Sqlite;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37
38namespace OpenSim.Data.SQLiteNG
39{
40 public class SQLiteGenericTableHandler<T> : SQLiteFramework where T: class, new()
41 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 protected Dictionary<string, FieldInfo> m_Fields =
45 new Dictionary<string, FieldInfo>();
46
47 protected List<string> m_ColumnNames = null;
48 protected string m_Realm;
49 protected FieldInfo m_DataField = null;
50
51 protected static SqliteConnection m_Connection;
52 private static bool m_initialized;
53
54 public SQLiteGenericTableHandler(string connectionString,
55 string realm, string storeName) : base(connectionString)
56 {
57 m_Realm = realm;
58
59 if (!m_initialized)
60 {
61 m_Connection = new SqliteConnection(connectionString);
62 Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString));
63 m_Connection.Open();
64
65 if (storeName != String.Empty)
66 {
67 Assembly assem = GetType().Assembly;
68 //SqliteConnection newConnection =
69 // (SqliteConnection)((ICloneable)m_Connection).Clone();
70 //newConnection.Open();
71
72 //Migration m = new Migration(newConnection, assem, storeName);
73 Migration m = new Migration(m_Connection, assem, storeName);
74 m.Update();
75 //newConnection.Close();
76 //newConnection.Dispose();
77 }
78
79 m_initialized = true;
80 }
81
82 Type t = typeof(T);
83 FieldInfo[] fields = t.GetFields(BindingFlags.Public |
84 BindingFlags.Instance |
85 BindingFlags.DeclaredOnly);
86
87 if (fields.Length == 0)
88 return;
89
90 foreach (FieldInfo f in fields)
91 {
92 if (f.Name != "Data")
93 m_Fields[f.Name] = f;
94 else
95 m_DataField = f;
96 }
97 }
98
99 private void CheckColumnNames(IDataReader reader)
100 {
101 if (m_ColumnNames != null)
102 return;
103
104 m_ColumnNames = new List<string>();
105
106 DataTable schemaTable = reader.GetSchemaTable();
107 foreach (DataRow row in schemaTable.Rows)
108 {
109 if (row["ColumnName"] != null &&
110 (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
111 m_ColumnNames.Add(row["ColumnName"].ToString());
112 }
113 }
114
115 public T[] Get(string field, string key)
116 {
117 return Get(new string[] { field }, new string[] { key });
118 }
119
120 public T[] Get(string[] fields, string[] keys)
121 {
122 if (fields.Length != keys.Length)
123 return new T[0];
124
125 List<string> terms = new List<string>();
126
127 SqliteCommand cmd = new SqliteCommand();
128
129 for (int i = 0 ; i < fields.Length ; i++)
130 {
131 cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
132 terms.Add("`" + fields[i] + "` = :" + fields[i]);
133 }
134
135 string where = String.Join(" and ", terms.ToArray());
136
137 string query = String.Format("select * from {0} where {1}",
138 m_Realm, where);
139
140 cmd.CommandText = query;
141
142 return DoQuery(cmd);
143 }
144
145 protected T[] DoQuery(SqliteCommand cmd)
146 {
147 IDataReader reader = ExecuteReader(cmd, m_Connection);
148 if (reader == null)
149 return new T[0];
150
151 CheckColumnNames(reader);
152
153 List<T> result = new List<T>();
154
155 while (reader.Read())
156 {
157 T row = new T();
158
159 foreach (string name in m_Fields.Keys)
160 {
161 if (m_Fields[name].GetValue(row) is bool)
162 {
163 int v = Convert.ToInt32(reader[name]);
164 m_Fields[name].SetValue(row, v != 0 ? true : false);
165 }
166 else if (m_Fields[name].GetValue(row) is UUID)
167 {
168 UUID uuid = UUID.Zero;
169
170 UUID.TryParse(reader[name].ToString(), out uuid);
171 m_Fields[name].SetValue(row, uuid);
172 }
173 else if (m_Fields[name].GetValue(row) is int)
174 {
175 int v = Convert.ToInt32(reader[name]);
176 m_Fields[name].SetValue(row, v);
177 }
178 else
179 {
180 m_Fields[name].SetValue(row, reader[name]);
181 }
182 }
183
184 if (m_DataField != null)
185 {
186 Dictionary<string, string> data =
187 new Dictionary<string, string>();
188
189 foreach (string col in m_ColumnNames)
190 {
191 data[col] = reader[col].ToString();
192 if (data[col] == null)
193 data[col] = String.Empty;
194 }
195
196 m_DataField.SetValue(row, data);
197 }
198
199 result.Add(row);
200 }
201
202 //CloseCommand(cmd);
203
204 return result.ToArray();
205 }
206
207 public T[] Get(string where)
208 {
209 SqliteCommand cmd = new SqliteCommand();
210
211 string query = String.Format("select * from {0} where {1}",
212 m_Realm, where);
213
214 cmd.CommandText = query;
215
216 return DoQuery(cmd);
217 }
218
219 public bool Store(T row)
220 {
221 SqliteCommand cmd = new SqliteCommand();
222
223 string query = "";
224 List<String> names = new List<String>();
225 List<String> values = new List<String>();
226
227 foreach (FieldInfo fi in m_Fields.Values)
228 {
229 names.Add(fi.Name);
230 values.Add(":" + fi.Name);
231 cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString()));
232 }
233
234 if (m_DataField != null)
235 {
236 Dictionary<string, string> data =
237 (Dictionary<string, string>)m_DataField.GetValue(row);
238
239 foreach (KeyValuePair<string, string> kvp in data)
240 {
241 names.Add(kvp.Key);
242 values.Add(":" + kvp.Key);
243 cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value));
244 }
245 }
246
247 query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
248
249 cmd.CommandText = query;
250
251 if (ExecuteNonQuery(cmd, m_Connection) > 0)
252 return true;
253
254 return false;
255 }
256
257 public bool Delete(string field, string val)
258 {
259 SqliteCommand cmd = new SqliteCommand();
260
261 cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field);
262 cmd.Parameters.Add(new SqliteParameter(field, val));
263
264 if (ExecuteNonQuery(cmd, m_Connection) > 0)
265 return true;
266
267 return false;
268 }
269 }
270}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
new file mode 100644
index 0000000..9207ca3
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
@@ -0,0 +1,909 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using Mono.Data.Sqlite;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37namespace OpenSim.Data.SQLiteNG
38{
39 /// <summary>
40 /// An Inventory Interface to the SQLite database
41 /// </summary>
42 public class SQLiteInventoryStore : SQLiteUtil, IInventoryDataPlugin
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private const string invItemsSelect = "select * from inventoryitems";
47 private const string invFoldersSelect = "select * from inventoryfolders";
48
49 private static SqliteConnection conn;
50 private static DataSet ds;
51 private static SqliteDataAdapter invItemsDa;
52 private static SqliteDataAdapter invFoldersDa;
53
54 private static bool m_Initialized = false;
55
56 public void Initialise()
57 {
58 m_log.Info("[SQLiteInventoryData]: " + Name + " cannot be default-initialized!");
59 throw new PluginNotInitialisedException(Name);
60 }
61
62 /// <summary>
63 /// <list type="bullet">
64 /// <item>Initialises Inventory interface</item>
65 /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
66 /// <item>use default URI if connect string string is empty.</item>
67 /// </list>
68 /// </summary>
69 /// <param name="dbconnect">connect string</param>
70 public void Initialise(string dbconnect)
71 {
72 if (!m_Initialized)
73 {
74 m_Initialized = true;
75
76 if (dbconnect == string.Empty)
77 {
78 dbconnect = "URI=file:inventoryStore.db,version=3";
79 }
80 m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect);
81 conn = new SqliteConnection(dbconnect);
82
83 conn.Open();
84
85 Assembly assem = GetType().Assembly;
86 Migration m = new Migration(conn, assem, "InventoryStore");
87 m.Update();
88
89 SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn);
90 invItemsDa = new SqliteDataAdapter(itemsSelectCmd);
91 // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa);
92
93 SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn);
94 invFoldersDa = new SqliteDataAdapter(foldersSelectCmd);
95
96 ds = new DataSet();
97
98 ds.Tables.Add(createInventoryFoldersTable());
99 invFoldersDa.Fill(ds.Tables["inventoryfolders"]);
100 setupFoldersCommands(invFoldersDa, conn);
101 CreateDataSetMapping(invFoldersDa, "inventoryfolders");
102 m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions");
103
104 ds.Tables.Add(createInventoryItemsTable());
105 invItemsDa.Fill(ds.Tables["inventoryitems"]);
106 setupItemsCommands(invItemsDa, conn);
107 CreateDataSetMapping(invItemsDa, "inventoryitems");
108 m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions");
109
110 ds.AcceptChanges();
111 }
112 }
113
114 /// <summary>
115 /// Closes the inventory interface
116 /// </summary>
117 public void Dispose()
118 {
119 if (conn != null)
120 {
121 conn.Close();
122 conn = null;
123 }
124 if (invItemsDa != null)
125 {
126 invItemsDa.Dispose();
127 invItemsDa = null;
128 }
129 if (invFoldersDa != null)
130 {
131 invFoldersDa.Dispose();
132 invFoldersDa = null;
133 }
134 if (ds != null)
135 {
136 ds.Dispose();
137 ds = null;
138 }
139 }
140
141 /// <summary>
142 ///
143 /// </summary>
144 /// <param name="row"></param>
145 /// <returns></returns>
146 public InventoryItemBase buildItem(DataRow row)
147 {
148 InventoryItemBase item = new InventoryItemBase();
149 item.ID = new UUID((string) row["UUID"]);
150 item.AssetID = new UUID((string) row["assetID"]);
151 item.AssetType = Convert.ToInt32(row["assetType"]);
152 item.InvType = Convert.ToInt32(row["invType"]);
153 item.Folder = new UUID((string) row["parentFolderID"]);
154 item.Owner = new UUID((string) row["avatarID"]);
155 item.CreatorId = (string)row["creatorsID"];
156 item.Name = (string) row["inventoryName"];
157 item.Description = (string) row["inventoryDescription"];
158
159 item.NextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]);
160 item.CurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]);
161 item.BasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]);
162 item.EveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]);
163 item.GroupPermissions = Convert.ToUInt32(row["inventoryGroupPermissions"]);
164
165 // new fields
166 if (!Convert.IsDBNull(row["salePrice"]))
167 item.SalePrice = Convert.ToInt32(row["salePrice"]);
168
169 if (!Convert.IsDBNull(row["saleType"]))
170 item.SaleType = Convert.ToByte(row["saleType"]);
171
172 if (!Convert.IsDBNull(row["creationDate"]))
173 item.CreationDate = Convert.ToInt32(row["creationDate"]);
174
175 if (!Convert.IsDBNull(row["groupID"]))
176 item.GroupID = new UUID((string)row["groupID"]);
177
178 if (!Convert.IsDBNull(row["groupOwned"]))
179 item.GroupOwned = Convert.ToBoolean(row["groupOwned"]);
180
181 if (!Convert.IsDBNull(row["Flags"]))
182 item.Flags = Convert.ToUInt32(row["Flags"]);
183
184 return item;
185 }
186
187 /// <summary>
188 /// Fill a database row with item data
189 /// </summary>
190 /// <param name="row"></param>
191 /// <param name="item"></param>
192 private static void fillItemRow(DataRow row, InventoryItemBase item)
193 {
194 row["UUID"] = item.ID.ToString();
195 row["assetID"] = item.AssetID.ToString();
196 row["assetType"] = item.AssetType;
197 row["invType"] = item.InvType;
198 row["parentFolderID"] = item.Folder.ToString();
199 row["avatarID"] = item.Owner.ToString();
200 row["creatorsID"] = item.CreatorId.ToString();
201 row["inventoryName"] = item.Name;
202 row["inventoryDescription"] = item.Description;
203
204 row["inventoryNextPermissions"] = item.NextPermissions;
205 row["inventoryCurrentPermissions"] = item.CurrentPermissions;
206 row["inventoryBasePermissions"] = item.BasePermissions;
207 row["inventoryEveryOnePermissions"] = item.EveryOnePermissions;
208 row["inventoryGroupPermissions"] = item.GroupPermissions;
209
210 // new fields
211 row["salePrice"] = item.SalePrice;
212 row["saleType"] = item.SaleType;
213 row["creationDate"] = item.CreationDate;
214 row["groupID"] = item.GroupID.ToString();
215 row["groupOwned"] = item.GroupOwned;
216 row["flags"] = item.Flags;
217 }
218
219 /// <summary>
220 /// Add inventory folder
221 /// </summary>
222 /// <param name="folder">Folder base</param>
223 /// <param name="add">true=create folder. false=update existing folder</param>
224 /// <remarks>nasty</remarks>
225 private void addFolder(InventoryFolderBase folder, bool add)
226 {
227 lock (ds)
228 {
229 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
230
231 DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString());
232 if (inventoryRow == null)
233 {
234 if (! add)
235 m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existant inventory folder: {0}", folder.ID);
236
237 inventoryRow = inventoryFolderTable.NewRow();
238 fillFolderRow(inventoryRow, folder);
239 inventoryFolderTable.Rows.Add(inventoryRow);
240 }
241 else
242 {
243 if (add)
244 m_log.ErrorFormat("Interface Misuse: Attempting to Add inventory folder that already exists: {0}", folder.ID);
245
246 fillFolderRow(inventoryRow, folder);
247 }
248
249 invFoldersDa.Update(ds, "inventoryfolders");
250 }
251 }
252
253 /// <summary>
254 /// Move an inventory folder
255 /// </summary>
256 /// <param name="folder">folder base</param>
257 private void moveFolder(InventoryFolderBase folder)
258 {
259 lock (ds)
260 {
261 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
262
263 DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString());
264 if (inventoryRow == null)
265 {
266 inventoryRow = inventoryFolderTable.NewRow();
267 fillFolderRow(inventoryRow, folder);
268 inventoryFolderTable.Rows.Add(inventoryRow);
269 }
270 else
271 {
272 moveFolderRow(inventoryRow, folder);
273 }
274
275 invFoldersDa.Update(ds, "inventoryfolders");
276 }
277 }
278
279 /// <summary>
280 /// add an item in inventory
281 /// </summary>
282 /// <param name="item">the item</param>
283 /// <param name="add">true=add item ; false=update existing item</param>
284 private void addItem(InventoryItemBase item, bool add)
285 {
286 lock (ds)
287 {
288 DataTable inventoryItemTable = ds.Tables["inventoryitems"];
289
290 DataRow inventoryRow = inventoryItemTable.Rows.Find(item.ID.ToString());
291 if (inventoryRow == null)
292 {
293 if (!add)
294 m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existant inventory item: {0}", item.ID);
295
296 inventoryRow = inventoryItemTable.NewRow();
297 fillItemRow(inventoryRow, item);
298 inventoryItemTable.Rows.Add(inventoryRow);
299 }
300 else
301 {
302 if (add)
303 m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Add inventory item that already exists: {0}", item.ID);
304
305 fillItemRow(inventoryRow, item);
306 }
307
308 invItemsDa.Update(ds, "inventoryitems");
309
310 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
311
312 inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString());
313 if (inventoryRow != null) //MySQL doesn't throw an exception here, so sqlite shouldn't either.
314 inventoryRow["version"] = (int)inventoryRow["version"] + 1;
315
316 invFoldersDa.Update(ds, "inventoryfolders");
317 }
318 }
319
320 /// <summary>
321 /// TODO : DataSet commit
322 /// </summary>
323 public void Shutdown()
324 {
325 // TODO: DataSet commit
326 }
327
328 /// <summary>
329 /// The name of this DB provider
330 /// </summary>
331 /// <returns>Name of DB provider</returns>
332 public string Name
333 {
334 get { return "SQLite Inventory Data Interface"; }
335 }
336
337 /// <summary>
338 /// Returns the version of this DB provider
339 /// </summary>
340 /// <returns>A string containing the DB provider version</returns>
341 public string Version
342 {
343 get
344 {
345 Module module = GetType().Module;
346 // string dllName = module.Assembly.ManifestModule.Name;
347 Version dllVersion = module.Assembly.GetName().Version;
348
349
350 return
351 string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
352 dllVersion.Revision);
353 }
354 }
355
356 /// <summary>
357 /// Returns a list of inventory items contained within the specified folder
358 /// </summary>
359 /// <param name="folderID">The UUID of the target folder</param>
360 /// <returns>A List of InventoryItemBase items</returns>
361 public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
362 {
363 lock (ds)
364 {
365 List<InventoryItemBase> retval = new List<InventoryItemBase>();
366 DataTable inventoryItemTable = ds.Tables["inventoryitems"];
367 string selectExp = "parentFolderID = '" + folderID + "'";
368 DataRow[] rows = inventoryItemTable.Select(selectExp);
369 foreach (DataRow row in rows)
370 {
371 retval.Add(buildItem(row));
372 }
373
374 return retval;
375 }
376 }
377
378 /// <summary>
379 /// Returns a list of the root folders within a users inventory
380 /// </summary>
381 /// <param name="user">The user whos inventory is to be searched</param>
382 /// <returns>A list of folder objects</returns>
383 public List<InventoryFolderBase> getUserRootFolders(UUID user)
384 {
385 return new List<InventoryFolderBase>();
386 }
387
388 // see InventoryItemBase.getUserRootFolder
389 public InventoryFolderBase getUserRootFolder(UUID user)
390 {
391 lock (ds)
392 {
393 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
394 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
395 string selectExp = "agentID = '" + user + "' AND parentID = '" + UUID.Zero + "'";
396 DataRow[] rows = inventoryFolderTable.Select(selectExp);
397 foreach (DataRow row in rows)
398 {
399 folders.Add(buildFolder(row));
400 }
401
402 // There should only ever be one root folder for a user. However, if there's more
403 // than one we'll simply use the first one rather than failing. It would be even
404 // nicer to print some message to this effect, but this feels like it's too low a
405 // to put such a message out, and it's too minor right now to spare the time to
406 // suitably refactor.
407 if (folders.Count > 0)
408 {
409 return folders[0];
410 }
411
412 return null;
413 }
414 }
415
416 /// <summary>
417 /// Append a list of all the child folders of a parent folder
418 /// </summary>
419 /// <param name="folders">list where folders will be appended</param>
420 /// <param name="parentID">ID of parent</param>
421 protected void getInventoryFolders(ref List<InventoryFolderBase> folders, UUID parentID)
422 {
423 lock (ds)
424 {
425 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
426 string selectExp = "parentID = '" + parentID + "'";
427 DataRow[] rows = inventoryFolderTable.Select(selectExp);
428 foreach (DataRow row in rows)
429 {
430 folders.Add(buildFolder(row));
431 }
432
433 }
434 }
435
436 /// <summary>
437 /// Returns a list of inventory folders contained in the folder 'parentID'
438 /// </summary>
439 /// <param name="parentID">The folder to get subfolders for</param>
440 /// <returns>A list of inventory folders</returns>
441 public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
442 {
443 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
444 getInventoryFolders(ref folders, parentID);
445 return folders;
446 }
447
448 /// <summary>
449 /// See IInventoryDataPlugin
450 /// </summary>
451 /// <param name="parentID"></param>
452 /// <returns></returns>
453 public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
454 {
455 /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one
456 * - We will only need to hit the database twice instead of n times.
457 * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned
458 * by the same person, each user only has 1 inventory heirarchy
459 * - The returned list is not ordered, instead of breadth-first ordered
460 There are basically 2 usage cases for getFolderHeirarchy:
461 1) Getting the user's entire inventory heirarchy when they log in
462 2) Finding a subfolder heirarchy to delete when emptying the trash.
463 This implementation will pull all inventory folders from the database, and then prune away any folder that
464 is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the
465 database than to make n requests. This pays off only if requested heirarchy is large.
466 By making this choice, we are making the worst case better at the cost of making the best case worse
467 - Francis
468 */
469
470 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
471 DataRow[] folderRows = null, parentRow;
472 InventoryFolderBase parentFolder = null;
473 lock (ds)
474 {
475 /* Fetch the parent folder from the database to determine the agent ID.
476 * Then fetch all inventory folders for that agent from the agent ID.
477 */
478 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
479 string selectExp = "UUID = '" + parentID + "'";
480 parentRow = inventoryFolderTable.Select(selectExp); // Assume at most 1 result
481 if (parentRow.GetLength(0) >= 1) // No result means parent folder does not exist
482 {
483 parentFolder = buildFolder(parentRow[0]);
484 UUID agentID = parentFolder.Owner;
485 selectExp = "agentID = '" + agentID + "'";
486 folderRows = inventoryFolderTable.Select(selectExp);
487 }
488
489 if (folderRows != null && folderRows.GetLength(0) >= 1) // No result means parent folder does not exist
490 { // or has no children
491 /* if we're querying the root folder, just return an unordered list of all folders in the user's
492 * inventory
493 */
494 if (parentFolder.ParentID == UUID.Zero)
495 {
496 foreach (DataRow row in folderRows)
497 {
498 InventoryFolderBase curFolder = buildFolder(row);
499 if (curFolder.ID != parentID) // Return all folders except the parent folder of heirarchy
500 folders.Add(buildFolder(row));
501 }
502 } // If requesting root folder
503 /* else we are querying a non-root folder. We currently have a list of all of the user's folders,
504 * we must construct a list of all folders in the heirarchy below parentID.
505 * Our first step will be to construct a hash table of all folders, indexed by parent ID.
506 * Once we have constructed the hash table, we will do a breadth-first traversal on the tree using the
507 * hash table to find child folders.
508 */
509 else
510 { // Querying a non-root folder
511
512 // Build a hash table of all user's inventory folders, indexed by each folder's parent ID
513 Dictionary<UUID, List<InventoryFolderBase>> hashtable =
514 new Dictionary<UUID, List<InventoryFolderBase>>(folderRows.GetLength(0));
515
516 foreach (DataRow row in folderRows)
517 {
518 InventoryFolderBase curFolder = buildFolder(row);
519 if (curFolder.ParentID != UUID.Zero) // Discard root of tree - not needed
520 {
521 if (hashtable.ContainsKey(curFolder.ParentID))
522 {
523 // Current folder already has a sibling - append to sibling list
524 hashtable[curFolder.ParentID].Add(curFolder);
525 }
526 else
527 {
528 List<InventoryFolderBase> siblingList = new List<InventoryFolderBase>();
529 siblingList.Add(curFolder);
530 // Current folder has no known (yet) siblings
531 hashtable.Add(curFolder.ParentID, siblingList);
532 }
533 }
534 } // For all inventory folders
535
536 // Note: Could release the ds lock here - we don't access folderRows or the database anymore.
537 // This is somewhat of a moot point as the callers of this function usually lock db anyways.
538
539 if (hashtable.ContainsKey(parentID)) // if requested folder does have children
540 folders.AddRange(hashtable[parentID]);
541
542 // BreadthFirstSearch build inventory tree **Note: folders.Count is *not* static
543 for (int i = 0; i < folders.Count; i++)
544 if (hashtable.ContainsKey(folders[i].ID))
545 folders.AddRange(hashtable[folders[i].ID]);
546
547 } // if requesting a subfolder heirarchy
548 } // if folder parentID exists and has children
549 } // lock ds
550 return folders;
551 }
552
553 /// <summary>
554 /// Returns an inventory item by its UUID
555 /// </summary>
556 /// <param name="item">The UUID of the item to be returned</param>
557 /// <returns>A class containing item information</returns>
558 public InventoryItemBase getInventoryItem(UUID item)
559 {
560 lock (ds)
561 {
562 DataRow row = ds.Tables["inventoryitems"].Rows.Find(item.ToString());
563 if (row != null)
564 {
565 return buildItem(row);
566 }
567 else
568 {
569 return null;
570 }
571 }
572 }
573
574 /// <summary>
575 /// Returns a specified inventory folder by its UUID
576 /// </summary>
577 /// <param name="folder">The UUID of the folder to be returned</param>
578 /// <returns>A class containing folder information</returns>
579 public InventoryFolderBase getInventoryFolder(UUID folder)
580 {
581 // TODO: Deep voodoo here. If you enable this code then
582 // multi region breaks. No idea why, but I figured it was
583 // better to leave multi region at this point. It does mean
584 // that you don't get to see system textures why creating
585 // clothes and the like. :(
586 lock (ds)
587 {
588 DataRow row = ds.Tables["inventoryfolders"].Rows.Find(folder.ToString());
589 if (row != null)
590 {
591 return buildFolder(row);
592 }
593 else
594 {
595 return null;
596 }
597 }
598 }
599
600 /// <summary>
601 /// Creates a new inventory item based on item
602 /// </summary>
603 /// <param name="item">The item to be created</param>
604 public void addInventoryItem(InventoryItemBase item)
605 {
606 addItem(item, true);
607 }
608
609 /// <summary>
610 /// Updates an inventory item with item (updates based on ID)
611 /// </summary>
612 /// <param name="item">The updated item</param>
613 public void updateInventoryItem(InventoryItemBase item)
614 {
615 addItem(item, false);
616 }
617
618 /// <summary>
619 /// Delete an inventory item
620 /// </summary>
621 /// <param name="item">The item UUID</param>
622 public void deleteInventoryItem(UUID itemID)
623 {
624 lock (ds)
625 {
626 DataTable inventoryItemTable = ds.Tables["inventoryitems"];
627
628 DataRow inventoryRow = inventoryItemTable.Rows.Find(itemID.ToString());
629 if (inventoryRow != null)
630 {
631 inventoryRow.Delete();
632 }
633
634 invItemsDa.Update(ds, "inventoryitems");
635 }
636 }
637
638 public InventoryItemBase queryInventoryItem(UUID itemID)
639 {
640 return getInventoryItem(itemID);
641 }
642
643 public InventoryFolderBase queryInventoryFolder(UUID folderID)
644 {
645 return getInventoryFolder(folderID);
646 }
647
648 /// <summary>
649 /// Delete all items in the specified folder
650 /// </summary>
651 /// <param name="folderId">id of the folder, whose item content should be deleted</param>
652 /// <todo>this is horribly inefficient, but I don't want to ruin the overall structure of this implementation</todo>
653 private void deleteItemsInFolder(UUID folderId)
654 {
655 List<InventoryItemBase> items = getInventoryInFolder(folderId);
656
657 foreach (InventoryItemBase i in items)
658 deleteInventoryItem(i.ID);
659 }
660
661 /// <summary>
662 /// Adds a new folder specified by folder
663 /// </summary>
664 /// <param name="folder">The inventory folder</param>
665 public void addInventoryFolder(InventoryFolderBase folder)
666 {
667 addFolder(folder, true);
668 }
669
670 /// <summary>
671 /// Updates a folder based on its ID with folder
672 /// </summary>
673 /// <param name="folder">The inventory folder</param>
674 public void updateInventoryFolder(InventoryFolderBase folder)
675 {
676 addFolder(folder, false);
677 }
678
679 /// <summary>
680 /// Moves a folder based on its ID with folder
681 /// </summary>
682 /// <param name="folder">The inventory folder</param>
683 public void moveInventoryFolder(InventoryFolderBase folder)
684 {
685 moveFolder(folder);
686 }
687
688 /// <summary>
689 /// Delete a folder
690 /// </summary>
691 /// <remarks>
692 /// This will clean-up any child folders and child items as well
693 /// </remarks>
694 /// <param name="folderID">the folder UUID</param>
695 public void deleteInventoryFolder(UUID folderID)
696 {
697 lock (ds)
698 {
699 List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
700
701 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
702 DataRow inventoryRow;
703
704 //Delete all sub-folders
705 foreach (InventoryFolderBase f in subFolders)
706 {
707 inventoryRow = inventoryFolderTable.Rows.Find(f.ID.ToString());
708 if (inventoryRow != null)
709 {
710 deleteItemsInFolder(f.ID);
711 inventoryRow.Delete();
712 }
713 }
714
715 //Delete the actual row
716 inventoryRow = inventoryFolderTable.Rows.Find(folderID.ToString());
717 if (inventoryRow != null)
718 {
719 deleteItemsInFolder(folderID);
720 inventoryRow.Delete();
721 }
722
723 invFoldersDa.Update(ds, "inventoryfolders");
724 }
725 }
726
727 /***********************************************************************
728 *
729 * Data Table definitions
730 *
731 **********************************************************************/
732
733 protected void CreateDataSetMapping(IDataAdapter da, string tableName)
734 {
735 ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName);
736 foreach (DataColumn col in ds.Tables[tableName].Columns)
737 {
738 dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName);
739 }
740 }
741
742 /// <summary>
743 /// Create the "inventoryitems" table
744 /// </summary>
745 private static DataTable createInventoryItemsTable()
746 {
747 DataTable inv = new DataTable("inventoryitems");
748
749 createCol(inv, "UUID", typeof (String)); //inventoryID
750 createCol(inv, "assetID", typeof (String));
751 createCol(inv, "assetType", typeof (Int32));
752 createCol(inv, "invType", typeof (Int32));
753 createCol(inv, "parentFolderID", typeof (String));
754 createCol(inv, "avatarID", typeof (String));
755 createCol(inv, "creatorsID", typeof (String));
756
757 createCol(inv, "inventoryName", typeof (String));
758 createCol(inv, "inventoryDescription", typeof (String));
759 // permissions
760 createCol(inv, "inventoryNextPermissions", typeof (Int32));
761 createCol(inv, "inventoryCurrentPermissions", typeof (Int32));
762 createCol(inv, "inventoryBasePermissions", typeof (Int32));
763 createCol(inv, "inventoryEveryOnePermissions", typeof (Int32));
764 createCol(inv, "inventoryGroupPermissions", typeof (Int32));
765
766 // sale info
767 createCol(inv, "salePrice", typeof(Int32));
768 createCol(inv, "saleType", typeof(Byte));
769
770 // creation date
771 createCol(inv, "creationDate", typeof(Int32));
772
773 // group info
774 createCol(inv, "groupID", typeof(String));
775 createCol(inv, "groupOwned", typeof(Boolean));
776
777 // Flags
778 createCol(inv, "flags", typeof(UInt32));
779
780 inv.PrimaryKey = new DataColumn[] { inv.Columns["UUID"] };
781 return inv;
782 }
783
784 /// <summary>
785 /// Creates the "inventoryfolders" table
786 /// </summary>
787 /// <returns></returns>
788 private static DataTable createInventoryFoldersTable()
789 {
790 DataTable fol = new DataTable("inventoryfolders");
791
792 createCol(fol, "UUID", typeof (String)); //folderID
793 createCol(fol, "name", typeof (String));
794 createCol(fol, "agentID", typeof (String));
795 createCol(fol, "parentID", typeof (String));
796 createCol(fol, "type", typeof (Int32));
797 createCol(fol, "version", typeof (Int32));
798
799 fol.PrimaryKey = new DataColumn[] {fol.Columns["UUID"]};
800 return fol;
801 }
802
803 /// <summary>
804 ///
805 /// </summary>
806 /// <param name="da"></param>
807 /// <param name="conn"></param>
808 private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
809 {
810 lock (ds)
811 {
812 da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]);
813 da.InsertCommand.Connection = conn;
814
815 da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]);
816 da.UpdateCommand.Connection = conn;
817
818 SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID");
819 delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
820 delete.Connection = conn;
821 da.DeleteCommand = delete;
822 }
823 }
824
825 /// <summary>
826 ///
827 /// </summary>
828 /// <param name="da"></param>
829 /// <param name="conn"></param>
830 private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn)
831 {
832 lock (ds)
833 {
834 da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]);
835 da.InsertCommand.Connection = conn;
836
837 da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]);
838 da.UpdateCommand.Connection = conn;
839
840 SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID");
841 delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
842 delete.Connection = conn;
843 da.DeleteCommand = delete;
844 }
845 }
846
847 /// <summary>
848 ///
849 /// </summary>
850 /// <param name="row"></param>
851 /// <returns></returns>
852 private static InventoryFolderBase buildFolder(DataRow row)
853 {
854 InventoryFolderBase folder = new InventoryFolderBase();
855 folder.ID = new UUID((string) row["UUID"]);
856 folder.Name = (string) row["name"];
857 folder.Owner = new UUID((string) row["agentID"]);
858 folder.ParentID = new UUID((string) row["parentID"]);
859 folder.Type = Convert.ToInt16(row["type"]);
860 folder.Version = Convert.ToUInt16(row["version"]);
861 return folder;
862 }
863
864 /// <summary>
865 ///
866 /// </summary>
867 /// <param name="row"></param>
868 /// <param name="folder"></param>
869 private static void fillFolderRow(DataRow row, InventoryFolderBase folder)
870 {
871 row["UUID"] = folder.ID.ToString();
872 row["name"] = folder.Name;
873 row["agentID"] = folder.Owner.ToString();
874 row["parentID"] = folder.ParentID.ToString();
875 row["type"] = folder.Type;
876 row["version"] = folder.Version;
877 }
878
879 /// <summary>
880 ///
881 /// </summary>
882 /// <param name="row"></param>
883 /// <param name="folder"></param>
884 private static void moveFolderRow(DataRow row, InventoryFolderBase folder)
885 {
886 row["UUID"] = folder.ID.ToString();
887 row["parentID"] = folder.ParentID.ToString();
888 }
889
890 public List<InventoryItemBase> fetchActiveGestures (UUID avatarID)
891 {
892 lock (ds)
893 {
894 List<InventoryItemBase> items = new List<InventoryItemBase>();
895
896 DataTable inventoryItemTable = ds.Tables["inventoryitems"];
897 string selectExp
898 = "avatarID = '" + avatarID + "' AND assetType = " + (int)AssetType.Gesture + " AND flags = 1";
899 //m_log.DebugFormat("[SQL]: sql = " + selectExp);
900 DataRow[] rows = inventoryItemTable.Select(selectExp);
901 foreach (DataRow row in rows)
902 {
903 items.Add(buildItem(row));
904 }
905 return items;
906 }
907 }
908 }
909}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
new file mode 100644
index 0000000..289d626
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
@@ -0,0 +1,2321 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Drawing;
32using System.IO;
33using System.Reflection;
34using log4net;
35using Mono.Data.Sqlite;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40
41namespace OpenSim.Data.SQLiteNG
42{
43 /// <summary>
44 /// A RegionData Interface to the SQLite database
45 /// </summary>
46 public class SQLiteRegionData : IRegionDataStore
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 private const string primSelect = "select * from prims";
51 private const string shapeSelect = "select * from primshapes";
52 private const string itemsSelect = "select * from primitems";
53 private const string terrainSelect = "select * from terrain limit 1";
54 private const string landSelect = "select * from land";
55 private const string landAccessListSelect = "select distinct * from landaccesslist";
56 private const string regionbanListSelect = "select * from regionban";
57 private const string regionSettingsSelect = "select * from regionsettings";
58
59 private DataSet ds;
60 private SqliteDataAdapter primDa;
61 private SqliteDataAdapter shapeDa;
62 private SqliteDataAdapter itemsDa;
63 private SqliteDataAdapter terrainDa;
64 private SqliteDataAdapter landDa;
65 private SqliteDataAdapter landAccessListDa;
66 private SqliteDataAdapter regionSettingsDa;
67
68 private SqliteConnection m_conn;
69
70 private String m_connectionString;
71
72 // Temporary attribute while this is experimental
73
74 /***********************************************************************
75 *
76 * Public Interface Functions
77 *
78 **********************************************************************/
79
80 /// <summary>
81 /// See IRegionDataStore
82 /// <list type="bullet">
83 /// <item>Initialises RegionData Interface</item>
84 /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
85 /// </list>
86 /// </summary>
87 /// <param name="connectionString">the connection string</param>
88 public void Initialise(string connectionString)
89 {
90 try
91 {
92 m_connectionString = connectionString;
93
94 ds = new DataSet("Region");
95
96 m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString);
97 m_conn = new SqliteConnection(m_connectionString);
98 m_conn.Open();
99
100 SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn);
101 primDa = new SqliteDataAdapter(primSelectCmd);
102
103 SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn);
104 shapeDa = new SqliteDataAdapter(shapeSelectCmd);
105 // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa);
106
107 SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn);
108 itemsDa = new SqliteDataAdapter(itemsSelectCmd);
109
110 SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn);
111 terrainDa = new SqliteDataAdapter(terrainSelectCmd);
112
113 SqliteCommand landSelectCmd = new SqliteCommand(landSelect, m_conn);
114 landDa = new SqliteDataAdapter(landSelectCmd);
115
116 SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, m_conn);
117 landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd);
118
119 SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn);
120 regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd);
121 // This actually does the roll forward assembly stuff
122 Assembly assem = GetType().Assembly;
123 Migration m = new Migration(m_conn, assem, "RegionStore");
124 m.Update();
125
126 lock (ds)
127 {
128 ds.Tables.Add(createPrimTable());
129 setupPrimCommands(primDa, m_conn);
130
131 ds.Tables.Add(createShapeTable());
132 setupShapeCommands(shapeDa, m_conn);
133
134 ds.Tables.Add(createItemsTable());
135 setupItemsCommands(itemsDa, m_conn);
136
137 ds.Tables.Add(createTerrainTable());
138 setupTerrainCommands(terrainDa, m_conn);
139
140 ds.Tables.Add(createLandTable());
141 setupLandCommands(landDa, m_conn);
142
143 ds.Tables.Add(createLandAccessListTable());
144 setupLandAccessCommands(landAccessListDa, m_conn);
145
146 ds.Tables.Add(createRegionSettingsTable());
147 setupRegionSettingsCommands(regionSettingsDa, m_conn);
148
149 // WORKAROUND: This is a work around for sqlite on
150 // windows, which gets really unhappy with blob columns
151 // that have no sample data in them. At some point we
152 // need to actually find a proper way to handle this.
153 try
154 {
155 primDa.Fill(ds.Tables["prims"]);
156 }
157 catch (Exception)
158 {
159 m_log.Info("[REGION DB]: Caught fill error on prims table");
160 }
161
162 try
163 {
164 shapeDa.Fill(ds.Tables["primshapes"]);
165 }
166 catch (Exception)
167 {
168 m_log.Info("[REGION DB]: Caught fill error on primshapes table");
169 }
170
171 try
172 {
173 terrainDa.Fill(ds.Tables["terrain"]);
174 }
175 catch (Exception)
176 {
177 m_log.Info("[REGION DB]: Caught fill error on terrain table");
178 }
179
180 try
181 {
182 landDa.Fill(ds.Tables["land"]);
183 }
184 catch (Exception)
185 {
186 m_log.Info("[REGION DB]: Caught fill error on land table");
187 }
188
189 try
190 {
191 landAccessListDa.Fill(ds.Tables["landaccesslist"]);
192 }
193 catch (Exception)
194 {
195 m_log.Info("[REGION DB]: Caught fill error on landaccesslist table");
196 }
197
198 try
199 {
200 regionSettingsDa.Fill(ds.Tables["regionsettings"]);
201 }
202 catch (Exception)
203 {
204 m_log.Info("[REGION DB]: Caught fill error on regionsettings table");
205 }
206
207 // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values!
208 // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409
209 // Possibly because we manually set up our own DataTables before connecting to the database
210 CreateDataSetMapping(primDa, "prims");
211 CreateDataSetMapping(shapeDa, "primshapes");
212 CreateDataSetMapping(itemsDa, "primitems");
213 CreateDataSetMapping(terrainDa, "terrain");
214 CreateDataSetMapping(landDa, "land");
215 CreateDataSetMapping(landAccessListDa, "landaccesslist");
216 CreateDataSetMapping(regionSettingsDa, "regionsettings");
217 }
218 }
219 catch (Exception e)
220 {
221 m_log.Error(e);
222 Environment.Exit(23);
223 }
224
225 return;
226 }
227
228 public void Dispose()
229 {
230 if (m_conn != null)
231 {
232 m_conn.Close();
233 m_conn = null;
234 }
235 if (ds != null)
236 {
237 ds.Dispose();
238 ds = null;
239 }
240 if (primDa != null)
241 {
242 primDa.Dispose();
243 primDa = null;
244 }
245 if (shapeDa != null)
246 {
247 shapeDa.Dispose();
248 shapeDa = null;
249 }
250 if (itemsDa != null)
251 {
252 itemsDa.Dispose();
253 itemsDa = null;
254 }
255 if (terrainDa != null)
256 {
257 terrainDa.Dispose();
258 terrainDa = null;
259 }
260 if (landDa != null)
261 {
262 landDa.Dispose();
263 landDa = null;
264 }
265 if (landAccessListDa != null)
266 {
267 landAccessListDa.Dispose();
268 landAccessListDa = null;
269 }
270 if (regionSettingsDa != null)
271 {
272 regionSettingsDa.Dispose();
273 regionSettingsDa = null;
274 }
275 }
276
277 public void StoreRegionSettings(RegionSettings rs)
278 {
279 lock (ds)
280 {
281 DataTable regionsettings = ds.Tables["regionsettings"];
282
283 DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString());
284 if (settingsRow == null)
285 {
286 settingsRow = regionsettings.NewRow();
287 fillRegionSettingsRow(settingsRow, rs);
288 regionsettings.Rows.Add(settingsRow);
289 }
290 else
291 {
292 fillRegionSettingsRow(settingsRow, rs);
293 }
294
295 Commit();
296 }
297 }
298 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
299 {
300 //This connector doesn't support the windlight module yet
301 //Return default LL windlight settings
302 return new RegionLightShareData();
303 }
304 public void StoreRegionWindlightSettings(RegionLightShareData wl)
305 {
306 //This connector doesn't support the windlight module yet
307 }
308 public RegionSettings LoadRegionSettings(UUID regionUUID)
309 {
310 lock (ds)
311 {
312 DataTable regionsettings = ds.Tables["regionsettings"];
313
314 string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
315 DataRow[] rawsettings = regionsettings.Select(searchExp);
316 if (rawsettings.Length == 0)
317 {
318 RegionSettings rs = new RegionSettings();
319 rs.RegionUUID = regionUUID;
320 rs.OnSave += StoreRegionSettings;
321
322 StoreRegionSettings(rs);
323
324 return rs;
325 }
326 DataRow row = rawsettings[0];
327
328 RegionSettings newSettings = buildRegionSettings(row);
329 newSettings.OnSave += StoreRegionSettings;
330
331 return newSettings;
332 }
333 }
334
335 /// <summary>
336 /// Adds an object into region storage
337 /// </summary>
338 /// <param name="obj">the object</param>
339 /// <param name="regionUUID">the region UUID</param>
340 public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
341 {
342 uint flags = obj.RootPart.GetEffectiveObjectFlags();
343
344 // Eligibility check
345 //
346 if ((flags & (uint)PrimFlags.Temporary) != 0)
347 return;
348 if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
349 return;
350
351 lock (ds)
352 {
353 foreach (SceneObjectPart prim in obj.Children.Values)
354 {
355// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
356 addPrim(prim, obj.UUID, regionUUID);
357 }
358 }
359
360 Commit();
361 // m_log.Info("[Dump of prims]: " + ds.GetXml());
362 }
363
364 /// <summary>
365 /// Removes an object from region storage
366 /// </summary>
367 /// <param name="obj">the object</param>
368 /// <param name="regionUUID">the region UUID</param>
369 public void RemoveObject(UUID obj, UUID regionUUID)
370 {
371 // m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.Guid, regionUUID);
372
373 DataTable prims = ds.Tables["prims"];
374 DataTable shapes = ds.Tables["primshapes"];
375
376 string selectExp = "SceneGroupID = '" + obj + "' and RegionUUID = '" + regionUUID + "'";
377 lock (ds)
378 {
379 DataRow[] primRows = prims.Select(selectExp);
380 foreach (DataRow row in primRows)
381 {
382 // Remove shape rows
383 UUID uuid = new UUID((string) row["UUID"]);
384 DataRow shapeRow = shapes.Rows.Find(uuid.ToString());
385 if (shapeRow != null)
386 {
387 shapeRow.Delete();
388 }
389
390 RemoveItems(uuid);
391
392 // Remove prim row
393 row.Delete();
394 }
395 }
396
397 Commit();
398 }
399
400 /// <summary>
401 /// Remove all persisted items of the given prim.
402 /// The caller must acquire the necessrary synchronization locks and commit or rollback changes.
403 /// </summary>
404 /// <param name="uuid">The item UUID</param>
405 private void RemoveItems(UUID uuid)
406 {
407 DataTable items = ds.Tables["primitems"];
408
409 String sql = String.Format("primID = '{0}'", uuid);
410 DataRow[] itemRows = items.Select(sql);
411
412 foreach (DataRow itemRow in itemRows)
413 {
414 itemRow.Delete();
415 }
416 }
417
418 /// <summary>
419 /// Load persisted objects from region storage.
420 /// </summary>
421 /// <param name="regionUUID">The region UUID</param>
422 /// <returns>List of loaded groups</returns>
423 public List<SceneObjectGroup> LoadObjects(UUID regionUUID)
424 {
425 Dictionary<UUID, SceneObjectGroup> createdObjects = new Dictionary<UUID, SceneObjectGroup>();
426
427 List<SceneObjectGroup> retvals = new List<SceneObjectGroup>();
428
429 DataTable prims = ds.Tables["prims"];
430 DataTable shapes = ds.Tables["primshapes"];
431
432 string byRegion = "RegionUUID = '" + regionUUID + "'";
433
434 lock (ds)
435 {
436 DataRow[] primsForRegion = prims.Select(byRegion);
437 m_log.Info("[REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
438
439 // First, create all groups
440 foreach (DataRow primRow in primsForRegion)
441 {
442 try
443 {
444 SceneObjectPart prim = null;
445
446 string uuid = (string) primRow["UUID"];
447 string objID = (string) primRow["SceneGroupID"];
448
449 if (uuid == objID) //is new SceneObjectGroup ?
450 {
451 prim = buildPrim(primRow);
452 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
453 if (shapeRow != null)
454 {
455 prim.Shape = buildShape(shapeRow);
456 }
457 else
458 {
459 m_log.Info(
460 "[REGION DB]: No shape found for prim in storage, so setting default box shape");
461 prim.Shape = PrimitiveBaseShape.Default;
462 }
463
464 SceneObjectGroup group = new SceneObjectGroup(prim);
465 createdObjects.Add(group.UUID, group);
466 retvals.Add(group);
467 LoadItems(prim);
468 }
469 }
470 catch (Exception e)
471 {
472 m_log.Error("[REGION DB]: Failed create prim object in new group, exception and data follows");
473 m_log.Info("[REGION DB]: " + e.ToString());
474 foreach (DataColumn col in prims.Columns)
475 {
476 m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
477 }
478 }
479 }
480
481 // Now fill the groups with part data
482 foreach (DataRow primRow in primsForRegion)
483 {
484 try
485 {
486 SceneObjectPart prim = null;
487
488 string uuid = (string) primRow["UUID"];
489 string objID = (string) primRow["SceneGroupID"];
490 if (uuid != objID) //is new SceneObjectGroup ?
491 {
492 prim = buildPrim(primRow);
493 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
494 if (shapeRow != null)
495 {
496 prim.Shape = buildShape(shapeRow);
497 }
498 else
499 {
500 m_log.Warn(
501 "[REGION DB]: No shape found for prim in storage, so setting default box shape");
502 prim.Shape = PrimitiveBaseShape.Default;
503 }
504
505 createdObjects[new UUID(objID)].AddPart(prim);
506 LoadItems(prim);
507 }
508 }
509 catch (Exception e)
510 {
511 m_log.Error("[REGION DB]: Failed create prim object in group, exception and data follows");
512 m_log.Info("[REGION DB]: " + e.ToString());
513 foreach (DataColumn col in prims.Columns)
514 {
515 m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
516 }
517 }
518 }
519 }
520 return retvals;
521 }
522
523 /// <summary>
524 /// Load in a prim's persisted inventory.
525 /// </summary>
526 /// <param name="prim">the prim</param>
527 private void LoadItems(SceneObjectPart prim)
528 {
529 //m_log.DebugFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID);
530
531 DataTable dbItems = ds.Tables["primitems"];
532 String sql = String.Format("primID = '{0}'", prim.UUID.ToString());
533 DataRow[] dbItemRows = dbItems.Select(sql);
534 IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
535
536 foreach (DataRow row in dbItemRows)
537 {
538 TaskInventoryItem item = buildItem(row);
539 inventory.Add(item);
540
541 //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID);
542 }
543
544 prim.Inventory.RestoreInventoryItems(inventory);
545 }
546
547 /// <summary>
548 /// Store a terrain revision in region storage
549 /// </summary>
550 /// <param name="ter">terrain heightfield</param>
551 /// <param name="regionID">region UUID</param>
552 public void StoreTerrain(double[,] ter, UUID regionID)
553 {
554 lock (ds)
555 {
556 int revision = Util.UnixTimeSinceEpoch();
557
558 // This is added to get rid of the infinitely growing
559 // terrain databases which negatively impact on SQLite
560 // over time. Before reenabling this feature there
561 // needs to be a limitter put on the number of
562 // revisions in the database, as this old
563 // implementation is a DOS attack waiting to happen.
564
565 using (
566 SqliteCommand cmd =
567 new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision",
568 m_conn))
569 {
570 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
571 cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
572 cmd.ExecuteNonQuery();
573 }
574
575 // the following is an work around for .NET. The perf
576 // issues associated with it aren't as bad as you think.
577 m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString());
578 String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
579 " values(:RegionUUID, :Revision, :Heightfield)";
580
581 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
582 {
583 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
584 cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
585 cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter)));
586 cmd.ExecuteNonQuery();
587 }
588 }
589 }
590
591 /// <summary>
592 /// Load the latest terrain revision from region storage
593 /// </summary>
594 /// <param name="regionID">the region UUID</param>
595 /// <returns>Heightfield data</returns>
596 public double[,] LoadTerrain(UUID regionID)
597 {
598 lock (ds)
599 {
600 double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
601 terret.Initialize();
602
603 String sql = "select RegionUUID, Revision, Heightfield from terrain" +
604 " where RegionUUID=:RegionUUID order by Revision desc";
605
606 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
607 {
608 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
609
610 using (IDataReader row = cmd.ExecuteReader())
611 {
612 int rev = 0;
613 if (row.Read())
614 {
615 // TODO: put this into a function
616 using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
617 {
618 using (BinaryReader br = new BinaryReader(str))
619 {
620 for (int x = 0; x < (int)Constants.RegionSize; x++)
621 {
622 for (int y = 0; y < (int)Constants.RegionSize; y++)
623 {
624 terret[x, y] = br.ReadDouble();
625 }
626 }
627 }
628 }
629 rev = Convert.ToInt32(row["Revision"]);
630 }
631 else
632 {
633 m_log.Info("[REGION DB]: No terrain found for region");
634 return null;
635 }
636
637 m_log.Info("[REGION DB]: Loaded terrain revision r" + rev.ToString());
638 }
639 }
640 return terret;
641 }
642 }
643
644 /// <summary>
645 ///
646 /// </summary>
647 /// <param name="globalID"></param>
648 public void RemoveLandObject(UUID globalID)
649 {
650 lock (ds)
651 {
652 // Can't use blanket SQL statements when using SqlAdapters unless you re-read the data into the adapter
653 // after you're done.
654 // replaced below code with the SqliteAdapter version.
655 //using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", m_conn))
656 //{
657 // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
658 // cmd.ExecuteNonQuery();
659 //}
660
661 //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", m_conn))
662 //{
663 // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
664 // cmd.ExecuteNonQuery();
665 //}
666
667 DataTable land = ds.Tables["land"];
668 DataTable landaccesslist = ds.Tables["landaccesslist"];
669 DataRow landRow = land.Rows.Find(globalID.ToString());
670 if (landRow != null)
671 {
672 land.Rows.Remove(landRow);
673 }
674 List<DataRow> rowsToDelete = new List<DataRow>();
675 foreach (DataRow rowToCheck in landaccesslist.Rows)
676 {
677 if (rowToCheck["LandUUID"].ToString() == globalID.ToString())
678 rowsToDelete.Add(rowToCheck);
679 }
680 for (int iter = 0; iter < rowsToDelete.Count; iter++)
681 {
682 landaccesslist.Rows.Remove(rowsToDelete[iter]);
683 }
684
685
686 }
687 Commit();
688 }
689
690 /// <summary>
691 ///
692 /// </summary>
693 /// <param name="parcel"></param>
694 public void StoreLandObject(ILandObject parcel)
695 {
696 lock (ds)
697 {
698 DataTable land = ds.Tables["land"];
699 DataTable landaccesslist = ds.Tables["landaccesslist"];
700
701 DataRow landRow = land.Rows.Find(parcel.LandData.GlobalID.ToString());
702 if (landRow == null)
703 {
704 landRow = land.NewRow();
705 fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
706 land.Rows.Add(landRow);
707 }
708 else
709 {
710 fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
711 }
712
713 // I know this caused someone issues before, but OpenSim is unusable if we leave this stuff around
714 //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", m_conn))
715 //{
716 // cmd.Parameters.Add(new SqliteParameter(":LandUUID", parcel.LandData.GlobalID.ToString()));
717 // cmd.ExecuteNonQuery();
718
719// }
720
721 // This is the slower.. but more appropriate thing to do
722
723 // We can't modify the table with direct queries before calling Commit() and re-filling them.
724 List<DataRow> rowsToDelete = new List<DataRow>();
725 foreach (DataRow rowToCheck in landaccesslist.Rows)
726 {
727 if (rowToCheck["LandUUID"].ToString() == parcel.LandData.GlobalID.ToString())
728 rowsToDelete.Add(rowToCheck);
729 }
730 for (int iter = 0; iter < rowsToDelete.Count; iter++)
731 {
732 landaccesslist.Rows.Remove(rowsToDelete[iter]);
733 }
734 rowsToDelete.Clear();
735 foreach (ParcelManager.ParcelAccessEntry entry in parcel.LandData.ParcelAccessList)
736 {
737 DataRow newAccessRow = landaccesslist.NewRow();
738 fillLandAccessRow(newAccessRow, entry, parcel.LandData.GlobalID);
739 landaccesslist.Rows.Add(newAccessRow);
740 }
741 }
742
743 Commit();
744 }
745
746 /// <summary>
747 ///
748 /// </summary>
749 /// <param name="regionUUID"></param>
750 /// <returns></returns>
751 public List<LandData> LoadLandObjects(UUID regionUUID)
752 {
753 List<LandData> landDataForRegion = new List<LandData>();
754 lock (ds)
755 {
756 DataTable land = ds.Tables["land"];
757 DataTable landaccesslist = ds.Tables["landaccesslist"];
758 string searchExp = "RegionUUID = '" + regionUUID + "'";
759 DataRow[] rawDataForRegion = land.Select(searchExp);
760 foreach (DataRow rawDataLand in rawDataForRegion)
761 {
762 LandData newLand = buildLandData(rawDataLand);
763 string accessListSearchExp = "LandUUID = '" + newLand.GlobalID + "'";
764 DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp);
765 foreach (DataRow rawDataLandAccess in rawDataForLandAccessList)
766 {
767 newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess));
768 }
769
770 landDataForRegion.Add(newLand);
771 }
772 }
773 return landDataForRegion;
774 }
775
776 /// <summary>
777 ///
778 /// </summary>
779 public void Commit()
780 {
781 m_log.Debug("[SQLITE]: Starting commit");
782 lock (ds)
783 {
784 primDa.Update(ds, "prims");
785 shapeDa.Update(ds, "primshapes");
786
787 itemsDa.Update(ds, "primitems");
788
789 terrainDa.Update(ds, "terrain");
790 landDa.Update(ds, "land");
791 landAccessListDa.Update(ds, "landaccesslist");
792 try
793 {
794 regionSettingsDa.Update(ds, "regionsettings");
795 }
796 catch (SqliteException SqlEx)
797 {
798 throw new Exception(
799 "There was a SQL error or connection string configuration error when saving the region settings. This could be a bug, it could also happen if ConnectionString is defined in the [DatabaseService] section of StandaloneCommon.ini in the config_include folder. This could also happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. If this is your first time running OpenSimulator, please restart the simulator and bug a developer to fix this!",
800 SqlEx);
801 }
802 ds.AcceptChanges();
803 }
804 }
805
806 /// <summary>
807 /// See <see cref="Commit"/>
808 /// </summary>
809 public void Shutdown()
810 {
811 Commit();
812 }
813
814 /***********************************************************************
815 *
816 * Database Definition Functions
817 *
818 * This should be db agnostic as we define them in ADO.NET terms
819 *
820 **********************************************************************/
821
822 protected void CreateDataSetMapping(IDataAdapter da, string tableName)
823 {
824 ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName);
825 foreach (DataColumn col in ds.Tables[tableName].Columns)
826 {
827 dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName);
828 }
829 }
830
831 /// <summary>
832 ///
833 /// </summary>
834 /// <param name="dt"></param>
835 /// <param name="name"></param>
836 /// <param name="type"></param>
837 private static void createCol(DataTable dt, string name, Type type)
838 {
839 DataColumn col = new DataColumn(name, type);
840 dt.Columns.Add(col);
841 }
842
843 /// <summary>
844 /// Creates the "terrain" table
845 /// </summary>
846 /// <returns>terrain table DataTable</returns>
847 private static DataTable createTerrainTable()
848 {
849 DataTable terrain = new DataTable("terrain");
850
851 createCol(terrain, "RegionUUID", typeof (String));
852 createCol(terrain, "Revision", typeof (Int32));
853 createCol(terrain, "Heightfield", typeof (Byte[]));
854
855 return terrain;
856 }
857
858 /// <summary>
859 /// Creates the "prims" table
860 /// </summary>
861 /// <returns>prim table DataTable</returns>
862 private static DataTable createPrimTable()
863 {
864 DataTable prims = new DataTable("prims");
865
866 createCol(prims, "UUID", typeof (String));
867 createCol(prims, "RegionUUID", typeof (String));
868 createCol(prims, "CreationDate", typeof (Int32));
869 createCol(prims, "Name", typeof (String));
870 createCol(prims, "SceneGroupID", typeof (String));
871 // various text fields
872 createCol(prims, "Text", typeof (String));
873 createCol(prims, "ColorR", typeof (Int32));
874 createCol(prims, "ColorG", typeof (Int32));
875 createCol(prims, "ColorB", typeof (Int32));
876 createCol(prims, "ColorA", typeof (Int32));
877 createCol(prims, "Description", typeof (String));
878 createCol(prims, "SitName", typeof (String));
879 createCol(prims, "TouchName", typeof (String));
880 // permissions
881 createCol(prims, "ObjectFlags", typeof (Int32));
882 createCol(prims, "CreatorID", typeof (String));
883 createCol(prims, "OwnerID", typeof (String));
884 createCol(prims, "GroupID", typeof (String));
885 createCol(prims, "LastOwnerID", typeof (String));
886 createCol(prims, "OwnerMask", typeof (Int32));
887 createCol(prims, "NextOwnerMask", typeof (Int32));
888 createCol(prims, "GroupMask", typeof (Int32));
889 createCol(prims, "EveryoneMask", typeof (Int32));
890 createCol(prims, "BaseMask", typeof (Int32));
891 // vectors
892 createCol(prims, "PositionX", typeof (Double));
893 createCol(prims, "PositionY", typeof (Double));
894 createCol(prims, "PositionZ", typeof (Double));
895 createCol(prims, "GroupPositionX", typeof (Double));
896 createCol(prims, "GroupPositionY", typeof (Double));
897 createCol(prims, "GroupPositionZ", typeof (Double));
898 createCol(prims, "VelocityX", typeof (Double));
899 createCol(prims, "VelocityY", typeof (Double));
900 createCol(prims, "VelocityZ", typeof (Double));
901 createCol(prims, "AngularVelocityX", typeof (Double));
902 createCol(prims, "AngularVelocityY", typeof (Double));
903 createCol(prims, "AngularVelocityZ", typeof (Double));
904 createCol(prims, "AccelerationX", typeof (Double));
905 createCol(prims, "AccelerationY", typeof (Double));
906 createCol(prims, "AccelerationZ", typeof (Double));
907 // quaternions
908 createCol(prims, "RotationX", typeof (Double));
909 createCol(prims, "RotationY", typeof (Double));
910 createCol(prims, "RotationZ", typeof (Double));
911 createCol(prims, "RotationW", typeof (Double));
912
913 // sit target
914 createCol(prims, "SitTargetOffsetX", typeof (Double));
915 createCol(prims, "SitTargetOffsetY", typeof (Double));
916 createCol(prims, "SitTargetOffsetZ", typeof (Double));
917
918 createCol(prims, "SitTargetOrientW", typeof (Double));
919 createCol(prims, "SitTargetOrientX", typeof (Double));
920 createCol(prims, "SitTargetOrientY", typeof (Double));
921 createCol(prims, "SitTargetOrientZ", typeof (Double));
922
923 createCol(prims, "PayPrice", typeof(Int32));
924 createCol(prims, "PayButton1", typeof(Int32));
925 createCol(prims, "PayButton2", typeof(Int32));
926 createCol(prims, "PayButton3", typeof(Int32));
927 createCol(prims, "PayButton4", typeof(Int32));
928
929 createCol(prims, "LoopedSound", typeof(String));
930 createCol(prims, "LoopedSoundGain", typeof(Double));
931 createCol(prims, "TextureAnimation", typeof(String));
932 createCol(prims, "ParticleSystem", typeof(String));
933
934 createCol(prims, "OmegaX", typeof(Double));
935 createCol(prims, "OmegaY", typeof(Double));
936 createCol(prims, "OmegaZ", typeof(Double));
937
938 createCol(prims, "CameraEyeOffsetX", typeof(Double));
939 createCol(prims, "CameraEyeOffsetY", typeof(Double));
940 createCol(prims, "CameraEyeOffsetZ", typeof(Double));
941
942 createCol(prims, "CameraAtOffsetX", typeof(Double));
943 createCol(prims, "CameraAtOffsetY", typeof(Double));
944 createCol(prims, "CameraAtOffsetZ", typeof(Double));
945
946 createCol(prims, "ForceMouselook", typeof(Int16));
947
948 createCol(prims, "ScriptAccessPin", typeof(Int32));
949
950 createCol(prims, "AllowedDrop", typeof(Int16));
951 createCol(prims, "DieAtEdge", typeof(Int16));
952
953 createCol(prims, "SalePrice", typeof(Int32));
954 createCol(prims, "SaleType", typeof(Int16));
955
956 // click action
957 createCol(prims, "ClickAction", typeof (Byte));
958
959 createCol(prims, "Material", typeof(Byte));
960
961 createCol(prims, "CollisionSound", typeof(String));
962 createCol(prims, "CollisionSoundVolume", typeof(Double));
963
964 createCol(prims, "VolumeDetect", typeof(Int16));
965
966 // Add in contraints
967 prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
968
969 return prims;
970 }
971
972 /// <summary>
973 /// Creates "primshapes" table
974 /// </summary>
975 /// <returns>shape table DataTable</returns>
976 private static DataTable createShapeTable()
977 {
978 DataTable shapes = new DataTable("primshapes");
979 createCol(shapes, "UUID", typeof (String));
980 // shape is an enum
981 createCol(shapes, "Shape", typeof (Int32));
982 // vectors
983 createCol(shapes, "ScaleX", typeof (Double));
984 createCol(shapes, "ScaleY", typeof (Double));
985 createCol(shapes, "ScaleZ", typeof (Double));
986 // paths
987 createCol(shapes, "PCode", typeof (Int32));
988 createCol(shapes, "PathBegin", typeof (Int32));
989 createCol(shapes, "PathEnd", typeof (Int32));
990 createCol(shapes, "PathScaleX", typeof (Int32));
991 createCol(shapes, "PathScaleY", typeof (Int32));
992 createCol(shapes, "PathShearX", typeof (Int32));
993 createCol(shapes, "PathShearY", typeof (Int32));
994 createCol(shapes, "PathSkew", typeof (Int32));
995 createCol(shapes, "PathCurve", typeof (Int32));
996 createCol(shapes, "PathRadiusOffset", typeof (Int32));
997 createCol(shapes, "PathRevolutions", typeof (Int32));
998 createCol(shapes, "PathTaperX", typeof (Int32));
999 createCol(shapes, "PathTaperY", typeof (Int32));
1000 createCol(shapes, "PathTwist", typeof (Int32));
1001 createCol(shapes, "PathTwistBegin", typeof (Int32));
1002 // profile
1003 createCol(shapes, "ProfileBegin", typeof (Int32));
1004 createCol(shapes, "ProfileEnd", typeof (Int32));
1005 createCol(shapes, "ProfileCurve", typeof (Int32));
1006 createCol(shapes, "ProfileHollow", typeof (Int32));
1007 createCol(shapes, "State", typeof(Int32));
1008 // text TODO: this isn't right, but I'm not sure the right
1009 // way to specify this as a blob atm
1010 createCol(shapes, "Texture", typeof (Byte[]));
1011 createCol(shapes, "ExtraParams", typeof (Byte[]));
1012
1013 shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
1014
1015 return shapes;
1016 }
1017
1018 /// <summary>
1019 /// creates "primitems" table
1020 /// </summary>
1021 /// <returns>item table DataTable</returns>
1022 private static DataTable createItemsTable()
1023 {
1024 DataTable items = new DataTable("primitems");
1025
1026 createCol(items, "itemID", typeof (String));
1027 createCol(items, "primID", typeof (String));
1028 createCol(items, "assetID", typeof (String));
1029 createCol(items, "parentFolderID", typeof (String));
1030
1031 createCol(items, "invType", typeof (Int32));
1032 createCol(items, "assetType", typeof (Int32));
1033
1034 createCol(items, "name", typeof (String));
1035 createCol(items, "description", typeof (String));
1036
1037 createCol(items, "creationDate", typeof (Int64));
1038 createCol(items, "creatorID", typeof (String));
1039 createCol(items, "ownerID", typeof (String));
1040 createCol(items, "lastOwnerID", typeof (String));
1041 createCol(items, "groupID", typeof (String));
1042
1043 createCol(items, "nextPermissions", typeof (UInt32));
1044 createCol(items, "currentPermissions", typeof (UInt32));
1045 createCol(items, "basePermissions", typeof (UInt32));
1046 createCol(items, "everyonePermissions", typeof (UInt32));
1047 createCol(items, "groupPermissions", typeof (UInt32));
1048 createCol(items, "flags", typeof (UInt32));
1049
1050 items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] };
1051
1052 return items;
1053 }
1054
1055 /// <summary>
1056 /// Creates "land" table
1057 /// </summary>
1058 /// <returns>land table DataTable</returns>
1059 private static DataTable createLandTable()
1060 {
1061 DataTable land = new DataTable("land");
1062 createCol(land, "UUID", typeof (String));
1063 createCol(land, "RegionUUID", typeof (String));
1064 createCol(land, "LocalLandID", typeof (UInt32));
1065
1066 // Bitmap is a byte[512]
1067 createCol(land, "Bitmap", typeof (Byte[]));
1068
1069 createCol(land, "Name", typeof (String));
1070 createCol(land, "Desc", typeof (String));
1071 createCol(land, "OwnerUUID", typeof (String));
1072 createCol(land, "IsGroupOwned", typeof (Boolean));
1073 createCol(land, "Area", typeof (Int32));
1074 createCol(land, "AuctionID", typeof (Int32)); //Unemplemented
1075 createCol(land, "Category", typeof (Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory
1076 createCol(land, "ClaimDate", typeof (Int32));
1077 createCol(land, "ClaimPrice", typeof (Int32));
1078 createCol(land, "GroupUUID", typeof (string));
1079 createCol(land, "SalePrice", typeof (Int32));
1080 createCol(land, "LandStatus", typeof (Int32)); //Enum. OpenMetaverse.Parcel.ParcelStatus
1081 createCol(land, "LandFlags", typeof (UInt32));
1082 createCol(land, "LandingType", typeof (Byte));
1083 createCol(land, "MediaAutoScale", typeof (Byte));
1084 createCol(land, "MediaTextureUUID", typeof (String));
1085 createCol(land, "MediaURL", typeof (String));
1086 createCol(land, "MusicURL", typeof (String));
1087 createCol(land, "PassHours", typeof (Double));
1088 createCol(land, "PassPrice", typeof (UInt32));
1089 createCol(land, "SnapshotUUID", typeof (String));
1090 createCol(land, "UserLocationX", typeof (Double));
1091 createCol(land, "UserLocationY", typeof (Double));
1092 createCol(land, "UserLocationZ", typeof (Double));
1093 createCol(land, "UserLookAtX", typeof (Double));
1094 createCol(land, "UserLookAtY", typeof (Double));
1095 createCol(land, "UserLookAtZ", typeof (Double));
1096 createCol(land, "AuthbuyerID", typeof(String));
1097 createCol(land, "OtherCleanTime", typeof(Int32));
1098 createCol(land, "Dwell", typeof(Int32));
1099
1100 land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]};
1101
1102 return land;
1103 }
1104
1105 /// <summary>
1106 /// create "landaccesslist" table
1107 /// </summary>
1108 /// <returns>Landacceslist DataTable</returns>
1109 private static DataTable createLandAccessListTable()
1110 {
1111 DataTable landaccess = new DataTable("landaccesslist");
1112 createCol(landaccess, "LandUUID", typeof (String));
1113 createCol(landaccess, "AccessUUID", typeof (String));
1114 createCol(landaccess, "Flags", typeof (UInt32));
1115
1116 return landaccess;
1117 }
1118
1119 private static DataTable createRegionSettingsTable()
1120 {
1121 DataTable regionsettings = new DataTable("regionsettings");
1122 createCol(regionsettings, "regionUUID", typeof(String));
1123 createCol(regionsettings, "block_terraform", typeof (Int32));
1124 createCol(regionsettings, "block_fly", typeof (Int32));
1125 createCol(regionsettings, "allow_damage", typeof (Int32));
1126 createCol(regionsettings, "restrict_pushing", typeof (Int32));
1127 createCol(regionsettings, "allow_land_resell", typeof (Int32));
1128 createCol(regionsettings, "allow_land_join_divide", typeof (Int32));
1129 createCol(regionsettings, "block_show_in_search", typeof (Int32));
1130 createCol(regionsettings, "agent_limit", typeof (Int32));
1131 createCol(regionsettings, "object_bonus", typeof (Double));
1132 createCol(regionsettings, "maturity", typeof (Int32));
1133 createCol(regionsettings, "disable_scripts", typeof (Int32));
1134 createCol(regionsettings, "disable_collisions", typeof (Int32));
1135 createCol(regionsettings, "disable_physics", typeof (Int32));
1136 createCol(regionsettings, "terrain_texture_1", typeof(String));
1137 createCol(regionsettings, "terrain_texture_2", typeof(String));
1138 createCol(regionsettings, "terrain_texture_3", typeof(String));
1139 createCol(regionsettings, "terrain_texture_4", typeof(String));
1140 createCol(regionsettings, "elevation_1_nw", typeof (Double));
1141 createCol(regionsettings, "elevation_2_nw", typeof (Double));
1142 createCol(regionsettings, "elevation_1_ne", typeof (Double));
1143 createCol(regionsettings, "elevation_2_ne", typeof (Double));
1144 createCol(regionsettings, "elevation_1_se", typeof (Double));
1145 createCol(regionsettings, "elevation_2_se", typeof (Double));
1146 createCol(regionsettings, "elevation_1_sw", typeof (Double));
1147 createCol(regionsettings, "elevation_2_sw", typeof (Double));
1148 createCol(regionsettings, "water_height", typeof (Double));
1149 createCol(regionsettings, "terrain_raise_limit", typeof (Double));
1150 createCol(regionsettings, "terrain_lower_limit", typeof (Double));
1151 createCol(regionsettings, "use_estate_sun", typeof (Int32));
1152 createCol(regionsettings, "sandbox", typeof (Int32));
1153 createCol(regionsettings, "sunvectorx",typeof (Double));
1154 createCol(regionsettings, "sunvectory",typeof (Double));
1155 createCol(regionsettings, "sunvectorz",typeof (Double));
1156 createCol(regionsettings, "fixed_sun", typeof (Int32));
1157 createCol(regionsettings, "sun_position", typeof (Double));
1158 createCol(regionsettings, "covenant", typeof(String));
1159 regionsettings.PrimaryKey = new DataColumn[] { regionsettings.Columns["regionUUID"] };
1160 return regionsettings;
1161 }
1162
1163 /***********************************************************************
1164 *
1165 * Convert between ADO.NET <=> OpenSim Objects
1166 *
1167 * These should be database independant
1168 *
1169 **********************************************************************/
1170
1171 /// <summary>
1172 ///
1173 /// </summary>
1174 /// <param name="row"></param>
1175 /// <returns></returns>
1176 private SceneObjectPart buildPrim(DataRow row)
1177 {
1178 // Code commented. Uncomment to test the unit test inline.
1179
1180 // The unit test mentions this commented code for the purposes
1181 // of debugging a unit test failure
1182
1183 // SceneObjectGroup sog = new SceneObjectGroup();
1184 // SceneObjectPart sop = new SceneObjectPart();
1185 // sop.LocalId = 1;
1186 // sop.Name = "object1";
1187 // sop.Description = "object1";
1188 // sop.Text = "";
1189 // sop.SitName = "";
1190 // sop.TouchName = "";
1191 // sop.UUID = UUID.Random();
1192 // sop.Shape = PrimitiveBaseShape.Default;
1193 // sog.SetRootPart(sop);
1194 // Add breakpoint in above line. Check sop fields.
1195
1196 // TODO: this doesn't work yet because something more
1197 // interesting has to be done to actually get these values
1198 // back out. Not enough time to figure it out yet.
1199
1200 SceneObjectPart prim = new SceneObjectPart();
1201 prim.UUID = new UUID((String) row["UUID"]);
1202 // explicit conversion of integers is required, which sort
1203 // of sucks. No idea if there is a shortcut here or not.
1204 prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
1205 prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"];
1206 // various text fields
1207 prim.Text = (String) row["Text"];
1208 prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
1209 Convert.ToInt32(row["ColorR"]),
1210 Convert.ToInt32(row["ColorG"]),
1211 Convert.ToInt32(row["ColorB"]));
1212 prim.Description = (String) row["Description"];
1213 prim.SitName = (String) row["SitName"];
1214 prim.TouchName = (String) row["TouchName"];
1215 // permissions
1216 prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]);
1217 prim.CreatorID = new UUID((String) row["CreatorID"]);
1218 prim.OwnerID = new UUID((String) row["OwnerID"]);
1219 prim.GroupID = new UUID((String) row["GroupID"]);
1220 prim.LastOwnerID = new UUID((String) row["LastOwnerID"]);
1221 prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]);
1222 prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]);
1223 prim.GroupMask = Convert.ToUInt32(row["GroupMask"]);
1224 prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]);
1225 prim.BaseMask = Convert.ToUInt32(row["BaseMask"]);
1226 // vectors
1227 prim.OffsetPosition = new Vector3(
1228 Convert.ToSingle(row["PositionX"]),
1229 Convert.ToSingle(row["PositionY"]),
1230 Convert.ToSingle(row["PositionZ"])
1231 );
1232 prim.GroupPosition = new Vector3(
1233 Convert.ToSingle(row["GroupPositionX"]),
1234 Convert.ToSingle(row["GroupPositionY"]),
1235 Convert.ToSingle(row["GroupPositionZ"])
1236 );
1237 prim.Velocity = new Vector3(
1238 Convert.ToSingle(row["VelocityX"]),
1239 Convert.ToSingle(row["VelocityY"]),
1240 Convert.ToSingle(row["VelocityZ"])
1241 );
1242 prim.AngularVelocity = new Vector3(
1243 Convert.ToSingle(row["AngularVelocityX"]),
1244 Convert.ToSingle(row["AngularVelocityY"]),
1245 Convert.ToSingle(row["AngularVelocityZ"])
1246 );
1247 prim.Acceleration = new Vector3(
1248 Convert.ToSingle(row["AccelerationX"]),
1249 Convert.ToSingle(row["AccelerationY"]),
1250 Convert.ToSingle(row["AccelerationZ"])
1251 );
1252 // quaternions
1253 prim.RotationOffset = new Quaternion(
1254 Convert.ToSingle(row["RotationX"]),
1255 Convert.ToSingle(row["RotationY"]),
1256 Convert.ToSingle(row["RotationZ"]),
1257 Convert.ToSingle(row["RotationW"])
1258 );
1259
1260 prim.SitTargetPositionLL = new Vector3(
1261 Convert.ToSingle(row["SitTargetOffsetX"]),
1262 Convert.ToSingle(row["SitTargetOffsetY"]),
1263 Convert.ToSingle(row["SitTargetOffsetZ"]));
1264 prim.SitTargetOrientationLL = new Quaternion(
1265 Convert.ToSingle(
1266 row["SitTargetOrientX"]),
1267 Convert.ToSingle(
1268 row["SitTargetOrientY"]),
1269 Convert.ToSingle(
1270 row["SitTargetOrientZ"]),
1271 Convert.ToSingle(
1272 row["SitTargetOrientW"]));
1273
1274 prim.ClickAction = Convert.ToByte(row["ClickAction"]);
1275 prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]);
1276 prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]);
1277 prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]);
1278 prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]);
1279 prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]);
1280
1281 prim.Sound = new UUID(row["LoopedSound"].ToString());
1282 prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
1283 prim.SoundFlags = 1; // If it's persisted at all, it's looped
1284
1285 if (!row.IsNull("TextureAnimation"))
1286 prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());
1287 if (!row.IsNull("ParticleSystem"))
1288 prim.ParticleSystem = Convert.FromBase64String(row["ParticleSystem"].ToString());
1289
1290 prim.AngularVelocity = new Vector3(
1291 Convert.ToSingle(row["OmegaX"]),
1292 Convert.ToSingle(row["OmegaY"]),
1293 Convert.ToSingle(row["OmegaZ"])
1294 );
1295
1296 prim.SetCameraEyeOffset(new Vector3(
1297 Convert.ToSingle(row["CameraEyeOffsetX"]),
1298 Convert.ToSingle(row["CameraEyeOffsetY"]),
1299 Convert.ToSingle(row["CameraEyeOffsetZ"])
1300 ));
1301
1302 prim.SetCameraAtOffset(new Vector3(
1303 Convert.ToSingle(row["CameraAtOffsetX"]),
1304 Convert.ToSingle(row["CameraAtOffsetY"]),
1305 Convert.ToSingle(row["CameraAtOffsetZ"])
1306 ));
1307
1308 if (Convert.ToInt16(row["ForceMouselook"]) != 0)
1309 prim.SetForceMouselook(true);
1310
1311 prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]);
1312
1313 if (Convert.ToInt16(row["AllowedDrop"]) != 0)
1314 prim.AllowedDrop = true;
1315
1316 if (Convert.ToInt16(row["DieAtEdge"]) != 0)
1317 prim.DIE_AT_EDGE = true;
1318
1319 prim.SalePrice = Convert.ToInt32(row["SalePrice"]);
1320 prim.ObjectSaleType = Convert.ToByte(row["SaleType"]);
1321
1322 prim.Material = Convert.ToByte(row["Material"]);
1323
1324 prim.CollisionSound = new UUID(row["CollisionSound"].ToString());
1325 prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]);
1326
1327 if (Convert.ToInt16(row["VolumeDetect"]) != 0)
1328 prim.VolumeDetectActive = true;
1329
1330 return prim;
1331 }
1332
1333 /// <summary>
1334 /// Build a prim inventory item from the persisted data.
1335 /// </summary>
1336 /// <param name="row"></param>
1337 /// <returns></returns>
1338 private static TaskInventoryItem buildItem(DataRow row)
1339 {
1340 TaskInventoryItem taskItem = new TaskInventoryItem();
1341
1342 taskItem.ItemID = new UUID((String)row["itemID"]);
1343 taskItem.ParentPartID = new UUID((String)row["primID"]);
1344 taskItem.AssetID = new UUID((String)row["assetID"]);
1345 taskItem.ParentID = new UUID((String)row["parentFolderID"]);
1346
1347 taskItem.InvType = Convert.ToInt32(row["invType"]);
1348 taskItem.Type = Convert.ToInt32(row["assetType"]);
1349
1350 taskItem.Name = (String)row["name"];
1351 taskItem.Description = (String)row["description"];
1352 taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
1353 taskItem.CreatorID = new UUID((String)row["creatorID"]);
1354 taskItem.OwnerID = new UUID((String)row["ownerID"]);
1355 taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]);
1356 taskItem.GroupID = new UUID((String)row["groupID"]);
1357
1358 taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
1359 taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
1360 taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
1361 taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
1362 taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
1363 taskItem.Flags = Convert.ToUInt32(row["flags"]);
1364
1365 return taskItem;
1366 }
1367
1368 /// <summary>
1369 /// Build a Land Data from the persisted data.
1370 /// </summary>
1371 /// <param name="row"></param>
1372 /// <returns></returns>
1373 private LandData buildLandData(DataRow row)
1374 {
1375 LandData newData = new LandData();
1376
1377 newData.GlobalID = new UUID((String) row["UUID"]);
1378 newData.LocalID = Convert.ToInt32(row["LocalLandID"]);
1379
1380 // Bitmap is a byte[512]
1381 newData.Bitmap = (Byte[]) row["Bitmap"];
1382
1383 newData.Name = (String) row["Name"];
1384 newData.Description = (String) row["Desc"];
1385 newData.OwnerID = (UUID)(String) row["OwnerUUID"];
1386 newData.IsGroupOwned = (Boolean) row["IsGroupOwned"];
1387 newData.Area = Convert.ToInt32(row["Area"]);
1388 newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented
1389 newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]);
1390 //Enum OpenMetaverse.Parcel.ParcelCategory
1391 newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]);
1392 newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]);
1393 newData.GroupID = new UUID((String) row["GroupUUID"]);
1394 newData.SalePrice = Convert.ToInt32(row["SalePrice"]);
1395 newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]);
1396 //Enum. OpenMetaverse.Parcel.ParcelStatus
1397 newData.Flags = Convert.ToUInt32(row["LandFlags"]);
1398 newData.LandingType = (Byte) row["LandingType"];
1399 newData.MediaAutoScale = (Byte) row["MediaAutoScale"];
1400 newData.MediaID = new UUID((String) row["MediaTextureUUID"]);
1401 newData.MediaURL = (String) row["MediaURL"];
1402 newData.MusicURL = (String) row["MusicURL"];
1403 newData.PassHours = Convert.ToSingle(row["PassHours"]);
1404 newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
1405 newData.SnapshotID = (UUID)(String) row["SnapshotUUID"];
1406 try
1407 {
1408
1409 newData.UserLocation =
1410 new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]),
1411 Convert.ToSingle(row["UserLocationZ"]));
1412 newData.UserLookAt =
1413 new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]),
1414 Convert.ToSingle(row["UserLookAtZ"]));
1415
1416 }
1417 catch (InvalidCastException)
1418 {
1419 m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name);
1420 newData.UserLocation = Vector3.Zero;
1421 newData.UserLookAt = Vector3.Zero;
1422 }
1423 newData.ParcelAccessList = new List<ParcelManager.ParcelAccessEntry>();
1424 UUID authBuyerID = UUID.Zero;
1425
1426 UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID);
1427
1428 newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
1429 newData.Dwell = Convert.ToInt32(row["Dwell"]);
1430
1431 return newData;
1432 }
1433
1434 private RegionSettings buildRegionSettings(DataRow row)
1435 {
1436 RegionSettings newSettings = new RegionSettings();
1437
1438 newSettings.RegionUUID = new UUID((string) row["regionUUID"]);
1439 newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]);
1440 newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]);
1441 newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]);
1442 newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]);
1443 newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]);
1444 newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]);
1445 newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]);
1446 newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]);
1447 newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]);
1448 newSettings.Maturity = Convert.ToInt32(row["maturity"]);
1449 newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]);
1450 newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]);
1451 newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]);
1452 newSettings.TerrainTexture1 = new UUID((String) row["terrain_texture_1"]);
1453 newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]);
1454 newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]);
1455 newSettings.TerrainTexture4 = new UUID((String) row["terrain_texture_4"]);
1456 newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]);
1457 newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]);
1458 newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]);
1459 newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]);
1460 newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]);
1461 newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]);
1462 newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]);
1463 newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]);
1464 newSettings.WaterHeight = Convert.ToDouble(row["water_height"]);
1465 newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
1466 newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
1467 newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
1468 newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
1469 newSettings.SunVector = new Vector3 (
1470 Convert.ToSingle(row["sunvectorx"]),
1471 Convert.ToSingle(row["sunvectory"]),
1472 Convert.ToSingle(row["sunvectorz"])
1473 );
1474 newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
1475 newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
1476 newSettings.Covenant = new UUID((String) row["covenant"]);
1477
1478 return newSettings;
1479 }
1480
1481 /// <summary>
1482 /// Build a land access entry from the persisted data.
1483 /// </summary>
1484 /// <param name="row"></param>
1485 /// <returns></returns>
1486 private static ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row)
1487 {
1488 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
1489 entry.AgentID = new UUID((string) row["AccessUUID"]);
1490 entry.Flags = (AccessList) row["Flags"];
1491 entry.Time = new DateTime();
1492 return entry;
1493 }
1494
1495 /// <summary>
1496 ///
1497 /// </summary>
1498 /// <param name="val"></param>
1499 /// <returns></returns>
1500 private static Array serializeTerrain(double[,] val)
1501 {
1502 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
1503 BinaryWriter bw = new BinaryWriter(str);
1504
1505 // TODO: COMPATIBILITY - Add byte-order conversions
1506 for (int x = 0; x < (int)Constants.RegionSize; x++)
1507 for (int y = 0; y < (int)Constants.RegionSize; y++)
1508 bw.Write(val[x, y]);
1509
1510 return str.ToArray();
1511 }
1512
1513// private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
1514// {
1515// row["RegionUUID"] = regionUUID;
1516// row["Revision"] = rev;
1517
1518 // MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize)*sizeof (double));
1519// BinaryWriter bw = new BinaryWriter(str);
1520
1521// // TODO: COMPATIBILITY - Add byte-order conversions
1522 // for (int x = 0; x < (int)Constants.RegionSize; x++)
1523 // for (int y = 0; y < (int)Constants.RegionSize; y++)
1524// bw.Write(val[x, y]);
1525
1526// row["Heightfield"] = str.ToArray();
1527// }
1528
1529 /// <summary>
1530 ///
1531 /// </summary>
1532 /// <param name="row"></param>
1533 /// <param name="prim"></param>
1534 /// <param name="sceneGroupID"></param>
1535 /// <param name="regionUUID"></param>
1536 private static void fillPrimRow(DataRow row, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
1537 {
1538 row["UUID"] = prim.UUID.ToString();
1539 row["RegionUUID"] = regionUUID.ToString();
1540 row["CreationDate"] = prim.CreationDate;
1541 row["Name"] = prim.Name;
1542 row["SceneGroupID"] = sceneGroupID.ToString();
1543 // the UUID of the root part for this SceneObjectGroup
1544 // various text fields
1545 row["Text"] = prim.Text;
1546 row["Description"] = prim.Description;
1547 row["SitName"] = prim.SitName;
1548 row["TouchName"] = prim.TouchName;
1549 // permissions
1550 row["ObjectFlags"] = prim.ObjectFlags;
1551 row["CreatorID"] = prim.CreatorID.ToString();
1552 row["OwnerID"] = prim.OwnerID.ToString();
1553 row["GroupID"] = prim.GroupID.ToString();
1554 row["LastOwnerID"] = prim.LastOwnerID.ToString();
1555 row["OwnerMask"] = prim.OwnerMask;
1556 row["NextOwnerMask"] = prim.NextOwnerMask;
1557 row["GroupMask"] = prim.GroupMask;
1558 row["EveryoneMask"] = prim.EveryoneMask;
1559 row["BaseMask"] = prim.BaseMask;
1560 // vectors
1561 row["PositionX"] = prim.OffsetPosition.X;
1562 row["PositionY"] = prim.OffsetPosition.Y;
1563 row["PositionZ"] = prim.OffsetPosition.Z;
1564 row["GroupPositionX"] = prim.GroupPosition.X;
1565 row["GroupPositionY"] = prim.GroupPosition.Y;
1566 row["GroupPositionZ"] = prim.GroupPosition.Z;
1567 row["VelocityX"] = prim.Velocity.X;
1568 row["VelocityY"] = prim.Velocity.Y;
1569 row["VelocityZ"] = prim.Velocity.Z;
1570 row["AngularVelocityX"] = prim.AngularVelocity.X;
1571 row["AngularVelocityY"] = prim.AngularVelocity.Y;
1572 row["AngularVelocityZ"] = prim.AngularVelocity.Z;
1573 row["AccelerationX"] = prim.Acceleration.X;
1574 row["AccelerationY"] = prim.Acceleration.Y;
1575 row["AccelerationZ"] = prim.Acceleration.Z;
1576 // quaternions
1577 row["RotationX"] = prim.RotationOffset.X;
1578 row["RotationY"] = prim.RotationOffset.Y;
1579 row["RotationZ"] = prim.RotationOffset.Z;
1580 row["RotationW"] = prim.RotationOffset.W;
1581
1582 // Sit target
1583 Vector3 sitTargetPos = prim.SitTargetPositionLL;
1584 row["SitTargetOffsetX"] = sitTargetPos.X;
1585 row["SitTargetOffsetY"] = sitTargetPos.Y;
1586 row["SitTargetOffsetZ"] = sitTargetPos.Z;
1587
1588 Quaternion sitTargetOrient = prim.SitTargetOrientationLL;
1589 row["SitTargetOrientW"] = sitTargetOrient.W;
1590 row["SitTargetOrientX"] = sitTargetOrient.X;
1591 row["SitTargetOrientY"] = sitTargetOrient.Y;
1592 row["SitTargetOrientZ"] = sitTargetOrient.Z;
1593 row["ColorR"] = Convert.ToInt32(prim.Color.R);
1594 row["ColorG"] = Convert.ToInt32(prim.Color.G);
1595 row["ColorB"] = Convert.ToInt32(prim.Color.B);
1596 row["ColorA"] = Convert.ToInt32(prim.Color.A);
1597 row["PayPrice"] = prim.PayPrice[0];
1598 row["PayButton1"] = prim.PayPrice[1];
1599 row["PayButton2"] = prim.PayPrice[2];
1600 row["PayButton3"] = prim.PayPrice[3];
1601 row["PayButton4"] = prim.PayPrice[4];
1602
1603
1604 row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
1605 row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
1606
1607 row["OmegaX"] = prim.AngularVelocity.X;
1608 row["OmegaY"] = prim.AngularVelocity.Y;
1609 row["OmegaZ"] = prim.AngularVelocity.Z;
1610
1611 row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X;
1612 row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y;
1613 row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z;
1614
1615 row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X;
1616 row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y;
1617 row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z;
1618
1619
1620 if ((prim.SoundFlags & 1) != 0) // Looped
1621 {
1622 row["LoopedSound"] = prim.Sound.ToString();
1623 row["LoopedSoundGain"] = prim.SoundGain;
1624 }
1625 else
1626 {
1627 row["LoopedSound"] = UUID.Zero.ToString();
1628 row["LoopedSoundGain"] = 0.0f;
1629 }
1630
1631 if (prim.GetForceMouselook())
1632 row["ForceMouselook"] = 1;
1633 else
1634 row["ForceMouselook"] = 0;
1635
1636 row["ScriptAccessPin"] = prim.ScriptAccessPin;
1637
1638 if (prim.AllowedDrop)
1639 row["AllowedDrop"] = 1;
1640 else
1641 row["AllowedDrop"] = 0;
1642
1643 if (prim.DIE_AT_EDGE)
1644 row["DieAtEdge"] = 1;
1645 else
1646 row["DieAtEdge"] = 0;
1647
1648 row["SalePrice"] = prim.SalePrice;
1649 row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType);
1650
1651 // click action
1652 row["ClickAction"] = prim.ClickAction;
1653
1654 row["SalePrice"] = prim.SalePrice;
1655 row["Material"] = prim.Material;
1656
1657 row["CollisionSound"] = prim.CollisionSound.ToString();
1658 row["CollisionSoundVolume"] = prim.CollisionSoundVolume;
1659 if (prim.VolumeDetectActive)
1660 row["VolumeDetect"] = 1;
1661 else
1662 row["VolumeDetect"] = 0;
1663
1664 }
1665
1666 /// <summary>
1667 ///
1668 /// </summary>
1669 /// <param name="row"></param>
1670 /// <param name="taskItem"></param>
1671 private static void fillItemRow(DataRow row, TaskInventoryItem taskItem)
1672 {
1673 row["itemID"] = taskItem.ItemID.ToString();
1674 row["primID"] = taskItem.ParentPartID.ToString();
1675 row["assetID"] = taskItem.AssetID.ToString();
1676 row["parentFolderID"] = taskItem.ParentID.ToString();
1677
1678 row["invType"] = taskItem.InvType;
1679 row["assetType"] = taskItem.Type;
1680
1681 row["name"] = taskItem.Name;
1682 row["description"] = taskItem.Description;
1683 row["creationDate"] = taskItem.CreationDate;
1684 row["creatorID"] = taskItem.CreatorID.ToString();
1685 row["ownerID"] = taskItem.OwnerID.ToString();
1686 row["lastOwnerID"] = taskItem.LastOwnerID.ToString();
1687 row["groupID"] = taskItem.GroupID.ToString();
1688 row["nextPermissions"] = taskItem.NextPermissions;
1689 row["currentPermissions"] = taskItem.CurrentPermissions;
1690 row["basePermissions"] = taskItem.BasePermissions;
1691 row["everyonePermissions"] = taskItem.EveryonePermissions;
1692 row["groupPermissions"] = taskItem.GroupPermissions;
1693 row["flags"] = taskItem.Flags;
1694 }
1695
1696 /// <summary>
1697 ///
1698 /// </summary>
1699 /// <param name="row"></param>
1700 /// <param name="land"></param>
1701 /// <param name="regionUUID"></param>
1702 private static void fillLandRow(DataRow row, LandData land, UUID regionUUID)
1703 {
1704 row["UUID"] = land.GlobalID.ToString();
1705 row["RegionUUID"] = regionUUID.ToString();
1706 row["LocalLandID"] = land.LocalID;
1707
1708 // Bitmap is a byte[512]
1709 row["Bitmap"] = land.Bitmap;
1710
1711 row["Name"] = land.Name;
1712 row["Desc"] = land.Description;
1713 row["OwnerUUID"] = land.OwnerID.ToString();
1714 row["IsGroupOwned"] = land.IsGroupOwned;
1715 row["Area"] = land.Area;
1716 row["AuctionID"] = land.AuctionID; //Unemplemented
1717 row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory
1718 row["ClaimDate"] = land.ClaimDate;
1719 row["ClaimPrice"] = land.ClaimPrice;
1720 row["GroupUUID"] = land.GroupID.ToString();
1721 row["SalePrice"] = land.SalePrice;
1722 row["LandStatus"] = land.Status; //Enum. OpenMetaverse.Parcel.ParcelStatus
1723 row["LandFlags"] = land.Flags;
1724 row["LandingType"] = land.LandingType;
1725 row["MediaAutoScale"] = land.MediaAutoScale;
1726 row["MediaTextureUUID"] = land.MediaID.ToString();
1727 row["MediaURL"] = land.MediaURL;
1728 row["MusicURL"] = land.MusicURL;
1729 row["PassHours"] = land.PassHours;
1730 row["PassPrice"] = land.PassPrice;
1731 row["SnapshotUUID"] = land.SnapshotID.ToString();
1732 row["UserLocationX"] = land.UserLocation.X;
1733 row["UserLocationY"] = land.UserLocation.Y;
1734 row["UserLocationZ"] = land.UserLocation.Z;
1735 row["UserLookAtX"] = land.UserLookAt.X;
1736 row["UserLookAtY"] = land.UserLookAt.Y;
1737 row["UserLookAtZ"] = land.UserLookAt.Z;
1738 row["AuthbuyerID"] = land.AuthBuyerID.ToString();
1739 row["OtherCleanTime"] = land.OtherCleanTime;
1740 row["Dwell"] = land.Dwell;
1741 }
1742
1743 /// <summary>
1744 ///
1745 /// </summary>
1746 /// <param name="row"></param>
1747 /// <param name="entry"></param>
1748 /// <param name="parcelID"></param>
1749 private static void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, UUID parcelID)
1750 {
1751 row["LandUUID"] = parcelID.ToString();
1752 row["AccessUUID"] = entry.AgentID.ToString();
1753 row["Flags"] = entry.Flags;
1754 }
1755
1756 private static void fillRegionSettingsRow(DataRow row, RegionSettings settings)
1757 {
1758 row["regionUUID"] = settings.RegionUUID.ToString();
1759 row["block_terraform"] = settings.BlockTerraform;
1760 row["block_fly"] = settings.BlockFly;
1761 row["allow_damage"] = settings.AllowDamage;
1762 row["restrict_pushing"] = settings.RestrictPushing;
1763 row["allow_land_resell"] = settings.AllowLandResell;
1764 row["allow_land_join_divide"] = settings.AllowLandJoinDivide;
1765 row["block_show_in_search"] = settings.BlockShowInSearch;
1766 row["agent_limit"] = settings.AgentLimit;
1767 row["object_bonus"] = settings.ObjectBonus;
1768 row["maturity"] = settings.Maturity;
1769 row["disable_scripts"] = settings.DisableScripts;
1770 row["disable_collisions"] = settings.DisableCollisions;
1771 row["disable_physics"] = settings.DisablePhysics;
1772 row["terrain_texture_1"] = settings.TerrainTexture1.ToString();
1773 row["terrain_texture_2"] = settings.TerrainTexture2.ToString();
1774 row["terrain_texture_3"] = settings.TerrainTexture3.ToString();
1775 row["terrain_texture_4"] = settings.TerrainTexture4.ToString();
1776 row["elevation_1_nw"] = settings.Elevation1NW;
1777 row["elevation_2_nw"] = settings.Elevation2NW;
1778 row["elevation_1_ne"] = settings.Elevation1NE;
1779 row["elevation_2_ne"] = settings.Elevation2NE;
1780 row["elevation_1_se"] = settings.Elevation1SE;
1781 row["elevation_2_se"] = settings.Elevation2SE;
1782 row["elevation_1_sw"] = settings.Elevation1SW;
1783 row["elevation_2_sw"] = settings.Elevation2SW;
1784 row["water_height"] = settings.WaterHeight;
1785 row["terrain_raise_limit"] = settings.TerrainRaiseLimit;
1786 row["terrain_lower_limit"] = settings.TerrainLowerLimit;
1787 row["use_estate_sun"] = settings.UseEstateSun;
1788 row["Sandbox"] = settings.Sandbox; // database uses upper case S for sandbox
1789 row["sunvectorx"] = settings.SunVector.X;
1790 row["sunvectory"] = settings.SunVector.Y;
1791 row["sunvectorz"] = settings.SunVector.Z;
1792 row["fixed_sun"] = settings.FixedSun;
1793 row["sun_position"] = settings.SunPosition;
1794 row["covenant"] = settings.Covenant.ToString();
1795 }
1796
1797 /// <summary>
1798 ///
1799 /// </summary>
1800 /// <param name="row"></param>
1801 /// <returns></returns>
1802 private PrimitiveBaseShape buildShape(DataRow row)
1803 {
1804 PrimitiveBaseShape s = new PrimitiveBaseShape();
1805 s.Scale = new Vector3(
1806 Convert.ToSingle(row["ScaleX"]),
1807 Convert.ToSingle(row["ScaleY"]),
1808 Convert.ToSingle(row["ScaleZ"])
1809 );
1810 // paths
1811 s.PCode = Convert.ToByte(row["PCode"]);
1812 s.PathBegin = Convert.ToUInt16(row["PathBegin"]);
1813 s.PathEnd = Convert.ToUInt16(row["PathEnd"]);
1814 s.PathScaleX = Convert.ToByte(row["PathScaleX"]);
1815 s.PathScaleY = Convert.ToByte(row["PathScaleY"]);
1816 s.PathShearX = Convert.ToByte(row["PathShearX"]);
1817 s.PathShearY = Convert.ToByte(row["PathShearY"]);
1818 s.PathSkew = Convert.ToSByte(row["PathSkew"]);
1819 s.PathCurve = Convert.ToByte(row["PathCurve"]);
1820 s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]);
1821 s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]);
1822 s.PathTaperX = Convert.ToSByte(row["PathTaperX"]);
1823 s.PathTaperY = Convert.ToSByte(row["PathTaperY"]);
1824 s.PathTwist = Convert.ToSByte(row["PathTwist"]);
1825 s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]);
1826 // profile
1827 s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]);
1828 s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]);
1829 s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]);
1830 s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]);
1831 s.State = Convert.ToByte(row["State"]);
1832
1833 byte[] textureEntry = (byte[])row["Texture"];
1834 s.TextureEntry = textureEntry;
1835
1836 s.ExtraParams = (byte[]) row["ExtraParams"];
1837 return s;
1838 }
1839
1840 /// <summary>
1841 ///
1842 /// </summary>
1843 /// <param name="row"></param>
1844 /// <param name="prim"></param>
1845 private static void fillShapeRow(DataRow row, SceneObjectPart prim)
1846 {
1847 PrimitiveBaseShape s = prim.Shape;
1848 row["UUID"] = prim.UUID.ToString();
1849 // shape is an enum
1850 row["Shape"] = 0;
1851 // vectors
1852 row["ScaleX"] = s.Scale.X;
1853 row["ScaleY"] = s.Scale.Y;
1854 row["ScaleZ"] = s.Scale.Z;
1855 // paths
1856 row["PCode"] = s.PCode;
1857 row["PathBegin"] = s.PathBegin;
1858 row["PathEnd"] = s.PathEnd;
1859 row["PathScaleX"] = s.PathScaleX;
1860 row["PathScaleY"] = s.PathScaleY;
1861 row["PathShearX"] = s.PathShearX;
1862 row["PathShearY"] = s.PathShearY;
1863 row["PathSkew"] = s.PathSkew;
1864 row["PathCurve"] = s.PathCurve;
1865 row["PathRadiusOffset"] = s.PathRadiusOffset;
1866 row["PathRevolutions"] = s.PathRevolutions;
1867 row["PathTaperX"] = s.PathTaperX;
1868 row["PathTaperY"] = s.PathTaperY;
1869 row["PathTwist"] = s.PathTwist;
1870 row["PathTwistBegin"] = s.PathTwistBegin;
1871 // profile
1872 row["ProfileBegin"] = s.ProfileBegin;
1873 row["ProfileEnd"] = s.ProfileEnd;
1874 row["ProfileCurve"] = s.ProfileCurve;
1875 row["ProfileHollow"] = s.ProfileHollow;
1876 row["State"] = s.State;
1877
1878 row["Texture"] = s.TextureEntry;
1879 row["ExtraParams"] = s.ExtraParams;
1880 }
1881
1882 /// <summary>
1883 ///
1884 /// </summary>
1885 /// <param name="prim"></param>
1886 /// <param name="sceneGroupID"></param>
1887 /// <param name="regionUUID"></param>
1888 private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
1889 {
1890
1891 DataTable prims = ds.Tables["prims"];
1892 DataTable shapes = ds.Tables["primshapes"];
1893
1894 DataRow primRow = prims.Rows.Find(prim.UUID.ToString());
1895 if (primRow == null)
1896 {
1897 primRow = prims.NewRow();
1898 fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
1899 prims.Rows.Add(primRow);
1900 }
1901 else
1902 {
1903 fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
1904 }
1905
1906 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
1907 if (shapeRow == null)
1908 {
1909 shapeRow = shapes.NewRow();
1910 fillShapeRow(shapeRow, prim);
1911 shapes.Rows.Add(shapeRow);
1912 }
1913 else
1914 {
1915 fillShapeRow(shapeRow, prim);
1916 }
1917 }
1918
1919 /// <summary>
1920 /// see IRegionDatastore
1921 /// </summary>
1922 /// <param name="primID"></param>
1923 /// <param name="items"></param>
1924 public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
1925 {
1926 m_log.InfoFormat("[REGION DB]: Entered StorePrimInventory with prim ID {0}", primID);
1927
1928 DataTable dbItems = ds.Tables["primitems"];
1929
1930 // For now, we're just going to crudely remove all the previous inventory items
1931 // no matter whether they have changed or not, and replace them with the current set.
1932 lock (ds)
1933 {
1934 RemoveItems(primID);
1935
1936 // repalce with current inventory details
1937 foreach (TaskInventoryItem newItem in items)
1938 {
1939// m_log.InfoFormat(
1940// "[DATASTORE]: ",
1941// "Adding item {0}, {1} to prim ID {2}",
1942// newItem.Name, newItem.ItemID, newItem.ParentPartID);
1943
1944 DataRow newItemRow = dbItems.NewRow();
1945 fillItemRow(newItemRow, newItem);
1946 dbItems.Rows.Add(newItemRow);
1947 }
1948 }
1949
1950 Commit();
1951 }
1952
1953 /***********************************************************************
1954 *
1955 * SQL Statement Creation Functions
1956 *
1957 * These functions create SQL statements for update, insert, and create.
1958 * They can probably be factored later to have a db independant
1959 * portion and a db specific portion
1960 *
1961 **********************************************************************/
1962
1963 /// <summary>
1964 /// Create an insert command
1965 /// </summary>
1966 /// <param name="table">table name</param>
1967 /// <param name="dt">data table</param>
1968 /// <returns>the created command</returns>
1969 /// <remarks>
1970 /// This is subtle enough to deserve some commentary.
1971 /// Instead of doing *lots* and *lots of hardcoded strings
1972 /// for database definitions we'll use the fact that
1973 /// realistically all insert statements look like "insert
1974 /// into A(b, c) values(:b, :c) on the parameterized query
1975 /// front. If we just have a list of b, c, etc... we can
1976 /// generate these strings instead of typing them out.
1977 /// </remarks>
1978 private static SqliteCommand createInsertCommand(string table, DataTable dt)
1979 {
1980 string[] cols = new string[dt.Columns.Count];
1981 for (int i = 0; i < dt.Columns.Count; i++)
1982 {
1983 DataColumn col = dt.Columns[i];
1984 cols[i] = col.ColumnName;
1985 }
1986
1987 string sql = "insert into " + table + "(";
1988 sql += String.Join(", ", cols);
1989 // important, the first ':' needs to be here, the rest get added in the join
1990 sql += ") values (:";
1991 sql += String.Join(", :", cols);
1992 sql += ")";
1993 m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql);
1994 SqliteCommand cmd = new SqliteCommand(sql);
1995
1996 // this provides the binding for all our parameters, so
1997 // much less code than it used to be
1998 foreach (DataColumn col in dt.Columns)
1999 {
2000 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
2001 }
2002 return cmd;
2003 }
2004
2005
2006 /// <summary>
2007 /// create an update command
2008 /// </summary>
2009 /// <param name="table">table name</param>
2010 /// <param name="pk"></param>
2011 /// <param name="dt"></param>
2012 /// <returns>the created command</returns>
2013 private static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
2014 {
2015 string sql = "update " + table + " set ";
2016 string subsql = String.Empty;
2017 foreach (DataColumn col in dt.Columns)
2018 {
2019 if (subsql.Length > 0)
2020 {
2021 // a map function would rock so much here
2022 subsql += ", ";
2023 }
2024 subsql += col.ColumnName + "= :" + col.ColumnName;
2025 }
2026 sql += subsql;
2027 sql += " where " + pk;
2028 SqliteCommand cmd = new SqliteCommand(sql);
2029
2030 // this provides the binding for all our parameters, so
2031 // much less code than it used to be
2032
2033 foreach (DataColumn col in dt.Columns)
2034 {
2035 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
2036 }
2037 return cmd;
2038 }
2039
2040 /// <summary>
2041 /// create an update command
2042 /// </summary>
2043 /// <param name="table">table name</param>
2044 /// <param name="pk"></param>
2045 /// <param name="dt"></param>
2046 /// <returns>the created command</returns>
2047 private static SqliteCommand createUpdateCommand(string table, string pk1, string pk2, DataTable dt)
2048 {
2049 string sql = "update " + table + " set ";
2050 string subsql = String.Empty;
2051 foreach (DataColumn col in dt.Columns)
2052 {
2053 if (subsql.Length > 0)
2054 {
2055 // a map function would rock so much here
2056 subsql += ", ";
2057 }
2058 subsql += col.ColumnName + "= :" + col.ColumnName;
2059 }
2060 sql += subsql;
2061 sql += " where " + pk1 + " and " + pk2;
2062 SqliteCommand cmd = new SqliteCommand(sql);
2063
2064 // this provides the binding for all our parameters, so
2065 // much less code than it used to be
2066
2067 foreach (DataColumn col in dt.Columns)
2068 {
2069 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
2070 }
2071 return cmd;
2072 }
2073
2074 /// <summary>
2075 ///
2076 /// </summary>
2077 /// <param name="dt">Data Table</param>
2078 /// <returns></returns>
2079 // private static string defineTable(DataTable dt)
2080 // {
2081 // string sql = "create table " + dt.TableName + "(";
2082 // string subsql = String.Empty;
2083 // foreach (DataColumn col in dt.Columns)
2084 // {
2085 // if (subsql.Length > 0)
2086 // {
2087 // // a map function would rock so much here
2088 // subsql += ",\n";
2089 // }
2090 // subsql += col.ColumnName + " " + sqliteType(col.DataType);
2091 // if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0])
2092 // {
2093 // subsql += " primary key";
2094 // }
2095 // }
2096 // sql += subsql;
2097 // sql += ")";
2098 // return sql;
2099 // }
2100
2101 /***********************************************************************
2102 *
2103 * Database Binding functions
2104 *
2105 * These will be db specific due to typing, and minor differences
2106 * in databases.
2107 *
2108 **********************************************************************/
2109
2110 ///<summary>
2111 /// This is a convenience function that collapses 5 repetitive
2112 /// lines for defining SqliteParameters to 2 parameters:
2113 /// column name and database type.
2114 ///
2115 /// It assumes certain conventions like :param as the param
2116 /// name to replace in parametrized queries, and that source
2117 /// version is always current version, both of which are fine
2118 /// for us.
2119 ///</summary>
2120 ///<returns>a built sqlite parameter</returns>
2121 private static SqliteParameter createSqliteParameter(string name, Type type)
2122 {
2123 SqliteParameter param = new SqliteParameter();
2124 param.ParameterName = ":" + name;
2125 param.DbType = dbtypeFromType(type);
2126 param.SourceColumn = name;
2127 param.SourceVersion = DataRowVersion.Current;
2128 return param;
2129 }
2130
2131 /// <summary>
2132 ///
2133 /// </summary>
2134 /// <param name="da"></param>
2135 /// <param name="conn"></param>
2136 private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
2137 {
2138 da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
2139 da.InsertCommand.Connection = conn;
2140
2141 da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
2142 da.UpdateCommand.Connection = conn;
2143
2144 SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
2145 delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
2146 delete.Connection = conn;
2147 da.DeleteCommand = delete;
2148 }
2149
2150 /// <summary>
2151 ///
2152 /// </summary>
2153 /// <param name="da"></param>
2154 /// <param name="conn"></param>
2155 private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
2156 {
2157 da.InsertCommand = createInsertCommand("primitems", ds.Tables["primitems"]);
2158 da.InsertCommand.Connection = conn;
2159
2160 da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", ds.Tables["primitems"]);
2161 da.UpdateCommand.Connection = conn;
2162
2163 SqliteCommand delete = new SqliteCommand("delete from primitems where itemID = :itemID");
2164 delete.Parameters.Add(createSqliteParameter("itemID", typeof (String)));
2165 delete.Connection = conn;
2166 da.DeleteCommand = delete;
2167 }
2168
2169 /// <summary>
2170 ///
2171 /// </summary>
2172 /// <param name="da"></param>
2173 /// <param name="conn"></param>
2174 private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn)
2175 {
2176 da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]);
2177 da.InsertCommand.Connection = conn;
2178 }
2179
2180 /// <summary>
2181 ///
2182 /// </summary>
2183 /// <param name="da"></param>
2184 /// <param name="conn"></param>
2185 private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn)
2186 {
2187 da.InsertCommand = createInsertCommand("land", ds.Tables["land"]);
2188 da.InsertCommand.Connection = conn;
2189
2190 da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]);
2191 da.UpdateCommand.Connection = conn;
2192
2193 SqliteCommand delete = new SqliteCommand("delete from land where UUID=:UUID");
2194 delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
2195 da.DeleteCommand = delete;
2196 da.DeleteCommand.Connection = conn;
2197 }
2198
2199 /// <summary>
2200 ///
2201 /// </summary>
2202 /// <param name="da"></param>
2203 /// <param name="conn"></param>
2204 private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn)
2205 {
2206 da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]);
2207 da.InsertCommand.Connection = conn;
2208
2209 da.UpdateCommand = createUpdateCommand("landaccesslist", "LandUUID=:landUUID", "AccessUUID=:AccessUUID", ds.Tables["landaccesslist"]);
2210 da.UpdateCommand.Connection = conn;
2211
2212 SqliteCommand delete = new SqliteCommand("delete from landaccesslist where LandUUID= :LandUUID and AccessUUID= :AccessUUID");
2213 delete.Parameters.Add(createSqliteParameter("LandUUID", typeof(String)));
2214 delete.Parameters.Add(createSqliteParameter("AccessUUID", typeof(String)));
2215 da.DeleteCommand = delete;
2216 da.DeleteCommand.Connection = conn;
2217
2218 }
2219
2220 private void setupRegionSettingsCommands(SqliteDataAdapter da, SqliteConnection conn)
2221 {
2222 da.InsertCommand = createInsertCommand("regionsettings", ds.Tables["regionsettings"]);
2223 da.InsertCommand.Connection = conn;
2224 da.UpdateCommand = createUpdateCommand("regionsettings", "regionUUID=:regionUUID", ds.Tables["regionsettings"]);
2225 da.UpdateCommand.Connection = conn;
2226 }
2227
2228 /// <summary>
2229 ///
2230 /// </summary>
2231 /// <param name="da"></param>
2232 /// <param name="conn"></param>
2233 private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
2234 {
2235 da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
2236 da.InsertCommand.Connection = conn;
2237
2238 da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]);
2239 da.UpdateCommand.Connection = conn;
2240
2241 SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID");
2242 delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
2243 delete.Connection = conn;
2244 da.DeleteCommand = delete;
2245 }
2246
2247 /***********************************************************************
2248 *
2249 * Type conversion functions
2250 *
2251 **********************************************************************/
2252
2253 /// <summary>
2254 /// Type conversion function
2255 /// </summary>
2256 /// <param name="type"></param>
2257 /// <returns></returns>
2258 private static DbType dbtypeFromType(Type type)
2259 {
2260 if (type == typeof (String))
2261 {
2262 return DbType.String;
2263 }
2264 else if (type == typeof (Int32))
2265 {
2266 return DbType.Int32;
2267 }
2268 else if (type == typeof (Double))
2269 {
2270 return DbType.Double;
2271 }
2272 else if (type == typeof (Byte))
2273 {
2274 return DbType.Byte;
2275 }
2276 else if (type == typeof (Double))
2277 {
2278 return DbType.Double;
2279 }
2280 else if (type == typeof (Byte[]))
2281 {
2282 return DbType.Binary;
2283 }
2284 else
2285 {
2286 return DbType.String;
2287 }
2288 }
2289
2290 static void PrintDataSet(DataSet ds)
2291 {
2292 // Print out any name and extended properties.
2293 Console.WriteLine("DataSet is named: {0}", ds.DataSetName);
2294 foreach (System.Collections.DictionaryEntry de in ds.ExtendedProperties)
2295 {
2296 Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
2297 }
2298 Console.WriteLine();
2299 foreach (DataTable dt in ds.Tables)
2300 {
2301 Console.WriteLine("=> {0} Table:", dt.TableName);
2302 // Print out the column names.
2303 for (int curCol = 0; curCol < dt.Columns.Count; curCol++)
2304 {
2305 Console.Write(dt.Columns[curCol].ColumnName + "\t");
2306 }
2307 Console.WriteLine("\n----------------------------------");
2308 // Print the DataTable.
2309 for (int curRow = 0; curRow < dt.Rows.Count; curRow++)
2310 {
2311 for (int curCol = 0; curCol < dt.Columns.Count; curCol++)
2312 {
2313 Console.Write(dt.Rows[curRow][curCol].ToString() + "\t");
2314 }
2315 Console.WriteLine();
2316 }
2317 }
2318 }
2319
2320 }
2321}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
new file mode 100644
index 0000000..f77159c
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using OpenMetaverse;
33using OpenSim.Framework;
34using Mono.Data.Sqlite;
35
36namespace OpenSim.Data.SQLiteNG
37{
38 public class SQLiteUserAccountData : SQLiteGenericTableHandler<UserAccountData>, IUserAccountData
39 {
40 public SQLiteUserAccountData(string connectionString, string realm)
41 : base(connectionString, realm, "UserAccount")
42 {
43 }
44
45 public UserAccountData[] GetUsers(UUID scopeID, string query)
46 {
47 string[] words = query.Split(new char[] {' '});
48
49 for (int i = 0 ; i < words.Length ; i++)
50 {
51 if (words[i].Length < 3)
52 {
53 if (i != words.Length - 1)
54 Array.Copy(words, i + 1, words, i, words.Length - i - 1);
55 Array.Resize(ref words, words.Length - 1);
56 }
57 }
58
59 if (words.Length == 0)
60 return new UserAccountData[0];
61
62 if (words.Length > 2)
63 return new UserAccountData[0];
64
65 SqliteCommand cmd = new SqliteCommand();
66
67 if (words.Length == 1)
68 {
69 cmd.CommandText = String.Format("select * from {0} where ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')",
70 m_Realm, scopeID.ToString(), words[0]);
71 }
72 else
73 {
74 cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')",
75 m_Realm, scopeID.ToString(), words[0], words[1]);
76 }
77
78 return DoQuery(cmd);
79 }
80 }
81}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs
new file mode 100644
index 0000000..82a2e37
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs
@@ -0,0 +1,307 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Data;
30using Mono.Data.Sqlite;
31
32namespace OpenSim.Data.SQLiteNG
33{
34 /// <summary>
35 /// A base class for methods needed by all SQLite database classes
36 /// </summary>
37 public class SQLiteUtil
38 {
39 /***********************************************************************
40 *
41 * Database Definition Helper Functions
42 *
43 * This should be db agnostic as we define them in ADO.NET terms
44 *
45 **********************************************************************/
46
47 /// <summary>
48 ///
49 /// </summary>
50 /// <param name="dt"></param>
51 /// <param name="name"></param>
52 /// <param name="type"></param>
53 public static void createCol(DataTable dt, string name, Type type)
54 {
55 DataColumn col = new DataColumn(name, type);
56 dt.Columns.Add(col);
57 }
58
59 /***********************************************************************
60 *
61 * SQL Statement Creation Functions
62 *
63 * These functions create SQL statements for update, insert, and create.
64 * They can probably be factored later to have a db independant
65 * portion and a db specific portion
66 *
67 **********************************************************************/
68
69 /// <summary>
70 /// Create an insert command
71 /// </summary>
72 /// <param name="table">table name</param>
73 /// <param name="dt">data table</param>
74 /// <returns>the created command</returns>
75 /// <remarks>
76 /// This is subtle enough to deserve some commentary.
77 /// Instead of doing *lots* and *lots of hardcoded strings
78 /// for database definitions we'll use the fact that
79 /// realistically all insert statements look like "insert
80 /// into A(b, c) values(:b, :c) on the parameterized query
81 /// front. If we just have a list of b, c, etc... we can
82 /// generate these strings instead of typing them out.
83 /// </remarks>
84 public static SqliteCommand createInsertCommand(string table, DataTable dt)
85 {
86
87 string[] cols = new string[dt.Columns.Count];
88 for (int i = 0; i < dt.Columns.Count; i++)
89 {
90 DataColumn col = dt.Columns[i];
91 cols[i] = col.ColumnName;
92 }
93
94 string sql = "insert into " + table + "(";
95 sql += String.Join(", ", cols);
96 // important, the first ':' needs to be here, the rest get added in the join
97 sql += ") values (:";
98 sql += String.Join(", :", cols);
99 sql += ")";
100 SqliteCommand cmd = new SqliteCommand(sql);
101
102 // this provides the binding for all our parameters, so
103 // much less code than it used to be
104 foreach (DataColumn col in dt.Columns)
105 {
106 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
107 }
108 return cmd;
109 }
110
111 /// <summary>
112 /// create an update command
113 /// </summary>
114 /// <param name="table">table name</param>
115 /// <param name="pk"></param>
116 /// <param name="dt"></param>
117 /// <returns>the created command</returns>
118 public static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
119 {
120 string sql = "update " + table + " set ";
121 string subsql = String.Empty;
122 foreach (DataColumn col in dt.Columns)
123 {
124 if (subsql.Length > 0)
125 {
126 // a map function would rock so much here
127 subsql += ", ";
128 }
129 subsql += col.ColumnName + "= :" + col.ColumnName;
130 }
131 sql += subsql;
132 sql += " where " + pk;
133 SqliteCommand cmd = new SqliteCommand(sql);
134
135 // this provides the binding for all our parameters, so
136 // much less code than it used to be
137
138 foreach (DataColumn col in dt.Columns)
139 {
140 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
141 }
142 return cmd;
143 }
144
145 /// <summary>
146 ///
147 /// </summary>
148 /// <param name="dt">Data Table</param>
149 /// <returns></returns>
150 public static string defineTable(DataTable dt)
151 {
152 string sql = "create table " + dt.TableName + "(";
153 string subsql = String.Empty;
154 foreach (DataColumn col in dt.Columns)
155 {
156 if (subsql.Length > 0)
157 {
158 // a map function would rock so much here
159 subsql += ",\n";
160 }
161 subsql += col.ColumnName + " " + sqliteType(col.DataType);
162 if (dt.PrimaryKey.Length > 0)
163 {
164 if (col == dt.PrimaryKey[0])
165 {
166 subsql += " primary key";
167 }
168 }
169 }
170 sql += subsql;
171 sql += ")";
172 return sql;
173 }
174
175 /***********************************************************************
176 *
177 * Database Binding functions
178 *
179 * These will be db specific due to typing, and minor differences
180 * in databases.
181 *
182 **********************************************************************/
183
184 ///<summary>
185 /// <para>
186 /// This is a convenience function that collapses 5 repetitive
187 /// lines for defining SqliteParameters to 2 parameters:
188 /// column name and database type.
189 /// </para>
190 ///
191 /// <para>
192 /// It assumes certain conventions like :param as the param
193 /// name to replace in parametrized queries, and that source
194 /// version is always current version, both of which are fine
195 /// for us.
196 /// </para>
197 ///</summary>
198 /// <param name="name"></param>
199 /// <param name="type"></param>
200 ///<returns>a built sqlite parameter</returns>
201 public static SqliteParameter createSqliteParameter(string name, Type type)
202 {
203 SqliteParameter param = new SqliteParameter();
204 param.ParameterName = ":" + name;
205 param.DbType = dbtypeFromType(type);
206 param.SourceColumn = name;
207 param.SourceVersion = DataRowVersion.Current;
208 return param;
209 }
210
211 /***********************************************************************
212 *
213 * Type conversion functions
214 *
215 **********************************************************************/
216
217 /// <summary>
218 /// Type conversion function
219 /// </summary>
220 /// <param name="type">a type</param>
221 /// <returns>a DbType</returns>
222 public static DbType dbtypeFromType(Type type)
223 {
224 if (type == typeof (String))
225 {
226 return DbType.String;
227 }
228 else if (type == typeof (Int32))
229 {
230 return DbType.Int32;
231 }
232 else if (type == typeof (UInt32))
233 {
234 return DbType.UInt32;
235 }
236 else if (type == typeof (Int64))
237 {
238 return DbType.Int64;
239 }
240 else if (type == typeof (UInt64))
241 {
242 return DbType.UInt64;
243 }
244 else if (type == typeof (Double))
245 {
246 return DbType.Double;
247 }
248 else if (type == typeof (Boolean))
249 {
250 return DbType.Boolean;
251 }
252 else if (type == typeof (Byte[]))
253 {
254 return DbType.Binary;
255 }
256 else
257 {
258 return DbType.String;
259 }
260 }
261
262 /// <summary>
263 /// </summary>
264 /// <param name="type">a Type</param>
265 /// <returns>a string</returns>
266 /// <remarks>this is something we'll need to implement for each db slightly differently.</remarks>
267 public static string sqliteType(Type type)
268 {
269 if (type == typeof (String))
270 {
271 return "varchar(255)";
272 }
273 else if (type == typeof (Int32))
274 {
275 return "integer";
276 }
277 else if (type == typeof (UInt32))
278 {
279 return "integer";
280 }
281 else if (type == typeof (Int64))
282 {
283 return "varchar(255)";
284 }
285 else if (type == typeof (UInt64))
286 {
287 return "varchar(255)";
288 }
289 else if (type == typeof (Double))
290 {
291 return "float";
292 }
293 else if (type == typeof (Boolean))
294 {
295 return "integer";
296 }
297 else if (type == typeof (Byte[]))
298 {
299 return "blob";
300 }
301 else
302 {
303 return "string";
304 }
305 }
306 }
307}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
new file mode 100644
index 0000000..a0c17f8
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
@@ -0,0 +1,155 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Data;
30using System.Reflection;
31using System.Collections.Generic;
32using Mono.Data.Sqlite;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37namespace OpenSim.Data.SQLiteNG
38{
39 /// <summary>
40 /// A MySQL Interface for the Asset Server
41 /// </summary>
42 public class SQLiteXInventoryData : IXInventoryData
43 {
44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private SQLiteGenericTableHandler<XInventoryFolder> m_Folders;
47 private SqliteItemHandler m_Items;
48
49 public SQLiteXInventoryData(string conn, string realm)
50 {
51 m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
52 conn, "inventoryfolders", "InventoryStore");
53 m_Items = new SqliteItemHandler(
54 conn, "inventoryitems", String.Empty);
55 }
56
57 public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
58 {
59 return m_Folders.Get(fields, vals);
60 }
61
62 public XInventoryItem[] GetItems(string[] fields, string[] vals)
63 {
64 return m_Items.Get(fields, vals);
65 }
66
67 public bool StoreFolder(XInventoryFolder folder)
68 {
69 return m_Folders.Store(folder);
70 }
71
72 public bool StoreItem(XInventoryItem item)
73 {
74 return m_Items.Store(item);
75 }
76
77 public bool DeleteFolders(string field, string val)
78 {
79 return m_Folders.Delete(field, val);
80 }
81
82 public bool DeleteItems(string field, string val)
83 {
84 return m_Items.Delete(field, val);
85 }
86
87 public bool MoveItem(string id, string newParent)
88 {
89 return m_Items.MoveItem(id, newParent);
90 }
91
92 public XInventoryItem[] GetActiveGestures(UUID principalID)
93 {
94 return m_Items.GetActiveGestures(principalID);
95 }
96
97 public int GetAssetPermissions(UUID principalID, UUID assetID)
98 {
99 return m_Items.GetAssetPermissions(principalID, assetID);
100 }
101 }
102
103 public class SqliteItemHandler : SQLiteGenericTableHandler<XInventoryItem>
104 {
105 public SqliteItemHandler(string c, string t, string m) :
106 base(c, t, m)
107 {
108 }
109
110 public bool MoveItem(string id, string newParent)
111 {
112 SqliteCommand cmd = new SqliteCommand();
113
114 cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
115 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
116 cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
117
118 return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
119 }
120
121 public XInventoryItem[] GetActiveGestures(UUID principalID)
122 {
123 SqliteCommand cmd = new SqliteCommand();
124 cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm);
125
126 cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString()));
127 cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture));
128
129 return DoQuery(cmd);
130 }
131
132 public int GetAssetPermissions(UUID principalID, UUID assetID)
133 {
134 SqliteCommand cmd = new SqliteCommand();
135
136 cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm);
137 cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
138 cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString()));
139
140 IDataReader reader = ExecuteReader(cmd, m_Connection);
141
142 int perms = 0;
143
144 while (reader.Read())
145 {
146 perms |= Convert.ToInt32(reader["inventoryCurrentPermissions"]);
147 }
148
149 reader.Close();
150 //CloseCommand(cmd);
151
152 return perms;
153 }
154 }
155}
diff --git a/OpenSim/Data/Tests/BasicAssetTest.cs b/OpenSim/Data/Tests/BasicAssetTest.cs
index 25aed61..e80cff9 100644
--- a/OpenSim/Data/Tests/BasicAssetTest.cs
+++ b/OpenSim/Data/Tests/BasicAssetTest.cs
@@ -66,9 +66,9 @@ namespace OpenSim.Data.Tests
66 [Test] 66 [Test]
67 public void T010_StoreSimpleAsset() 67 public void T010_StoreSimpleAsset()
68 { 68 {
69 AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); 69 AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
70 AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture); 70 AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, UUID.Zero.ToString());
71 AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture); 71 AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture, UUID.Zero.ToString());
72 a1.Data = asset1; 72 a1.Data = asset1;
73 a2.Data = asset1; 73 a2.Data = asset1;
74 a3.Data = asset1; 74 a3.Data = asset1;
@@ -78,12 +78,15 @@ namespace OpenSim.Data.Tests
78 .DontScramble(x => x.ID) 78 .DontScramble(x => x.ID)
79 .DontScramble(x => x.FullID) 79 .DontScramble(x => x.FullID)
80 .DontScramble(x => x.Metadata.ID) 80 .DontScramble(x => x.Metadata.ID)
81 .DontScramble(x => x.Metadata.CreatorID)
82 .DontScramble(x => x.Metadata.ContentType)
81 .DontScramble(x => x.Metadata.FullID); 83 .DontScramble(x => x.Metadata.FullID);
82 84
83 scrambler.Scramble(a1); 85 scrambler.Scramble(a1);
84 scrambler.Scramble(a2); 86 scrambler.Scramble(a2);
85 scrambler.Scramble(a3); 87 scrambler.Scramble(a3);
86 88
89
87 db.StoreAsset(a1); 90 db.StoreAsset(a1);
88 db.StoreAsset(a2); 91 db.StoreAsset(a2);
89 db.StoreAsset(a3); 92 db.StoreAsset(a3);
diff --git a/OpenSim/Data/Tests/BasicEstateTest.cs b/OpenSim/Data/Tests/BasicEstateTest.cs
index 907bb38..d14d405 100644
--- a/OpenSim/Data/Tests/BasicEstateTest.cs
+++ b/OpenSim/Data/Tests/BasicEstateTest.cs
@@ -158,7 +158,7 @@ namespace OpenSim.Data.Tests
158 public void T012_EstateSettingsRandomStorage() 158 public void T012_EstateSettingsRandomStorage()
159 { 159 {
160 // Letting estate store generate rows to database for us 160 // Letting estate store generate rows to database for us
161 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID); 161 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
162 new PropertyScrambler<EstateSettings>() 162 new PropertyScrambler<EstateSettings>()
163 .DontScramble(x=>x.EstateID) 163 .DontScramble(x=>x.EstateID)
164 .Scramble(originalSettings); 164 .Scramble(originalSettings);
@@ -167,7 +167,7 @@ namespace OpenSim.Data.Tests
167 db.StoreEstateSettings(originalSettings); 167 db.StoreEstateSettings(originalSettings);
168 168
169 // Loading settings to another instance variable. 169 // Loading settings to another instance variable.
170 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID); 170 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID, true);
171 171
172 // Checking that loaded values are correct. 172 // Checking that loaded values are correct.
173 Assert.That(loadedSettings, Constraints.PropertyCompareConstraint(originalSettings)); 173 Assert.That(loadedSettings, Constraints.PropertyCompareConstraint(originalSettings));
@@ -177,7 +177,7 @@ namespace OpenSim.Data.Tests
177 public void T020_EstateSettingsManagerList() 177 public void T020_EstateSettingsManagerList()
178 { 178 {
179 // Letting estate store generate rows to database for us 179 // Letting estate store generate rows to database for us
180 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID); 180 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
181 181
182 originalSettings.EstateManagers = new UUID[] { MANAGER_ID_1, MANAGER_ID_2 }; 182 originalSettings.EstateManagers = new UUID[] { MANAGER_ID_1, MANAGER_ID_2 };
183 183
@@ -185,7 +185,7 @@ namespace OpenSim.Data.Tests
185 db.StoreEstateSettings(originalSettings); 185 db.StoreEstateSettings(originalSettings);
186 186
187 // Loading settings to another instance variable. 187 // Loading settings to another instance variable.
188 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID); 188 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID, true);
189 189
190 Assert.AreEqual(2, loadedSettings.EstateManagers.Length); 190 Assert.AreEqual(2, loadedSettings.EstateManagers.Length);
191 Assert.AreEqual(MANAGER_ID_1, loadedSettings.EstateManagers[0]); 191 Assert.AreEqual(MANAGER_ID_1, loadedSettings.EstateManagers[0]);
@@ -196,7 +196,7 @@ namespace OpenSim.Data.Tests
196 public void T021_EstateSettingsUserList() 196 public void T021_EstateSettingsUserList()
197 { 197 {
198 // Letting estate store generate rows to database for us 198 // Letting estate store generate rows to database for us
199 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID); 199 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
200 200
201 originalSettings.EstateAccess = new UUID[] { USER_ID_1, USER_ID_2 }; 201 originalSettings.EstateAccess = new UUID[] { USER_ID_1, USER_ID_2 };
202 202
@@ -204,7 +204,7 @@ namespace OpenSim.Data.Tests
204 db.StoreEstateSettings(originalSettings); 204 db.StoreEstateSettings(originalSettings);
205 205
206 // Loading settings to another instance variable. 206 // Loading settings to another instance variable.
207 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID); 207 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID, true);
208 208
209 Assert.AreEqual(2, loadedSettings.EstateAccess.Length); 209 Assert.AreEqual(2, loadedSettings.EstateAccess.Length);
210 Assert.AreEqual(USER_ID_1, loadedSettings.EstateAccess[0]); 210 Assert.AreEqual(USER_ID_1, loadedSettings.EstateAccess[0]);
@@ -215,7 +215,7 @@ namespace OpenSim.Data.Tests
215 public void T022_EstateSettingsGroupList() 215 public void T022_EstateSettingsGroupList()
216 { 216 {
217 // Letting estate store generate rows to database for us 217 // Letting estate store generate rows to database for us
218 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID); 218 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
219 219
220 originalSettings.EstateGroups = new UUID[] { GROUP_ID_1, GROUP_ID_2 }; 220 originalSettings.EstateGroups = new UUID[] { GROUP_ID_1, GROUP_ID_2 };
221 221
@@ -223,7 +223,7 @@ namespace OpenSim.Data.Tests
223 db.StoreEstateSettings(originalSettings); 223 db.StoreEstateSettings(originalSettings);
224 224
225 // Loading settings to another instance variable. 225 // Loading settings to another instance variable.
226 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID); 226 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID, true);
227 227
228 Assert.AreEqual(2, loadedSettings.EstateAccess.Length); 228 Assert.AreEqual(2, loadedSettings.EstateAccess.Length);
229 Assert.AreEqual(GROUP_ID_1, loadedSettings.EstateGroups[0]); 229 Assert.AreEqual(GROUP_ID_1, loadedSettings.EstateGroups[0]);
@@ -234,7 +234,7 @@ namespace OpenSim.Data.Tests
234 public void T022_EstateSettingsBanList() 234 public void T022_EstateSettingsBanList()
235 { 235 {
236 // Letting estate store generate rows to database for us 236 // Letting estate store generate rows to database for us
237 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID); 237 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
238 238
239 EstateBan estateBan1 = new EstateBan(); 239 EstateBan estateBan1 = new EstateBan();
240 estateBan1.BannedUserID = DataTestUtil.UUID_MIN; 240 estateBan1.BannedUserID = DataTestUtil.UUID_MIN;
@@ -248,7 +248,7 @@ namespace OpenSim.Data.Tests
248 db.StoreEstateSettings(originalSettings); 248 db.StoreEstateSettings(originalSettings);
249 249
250 // Loading settings to another instance variable. 250 // Loading settings to another instance variable.
251 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID); 251 EstateSettings loadedSettings = db.LoadEstateSettings(REGION_ID, true);
252 252
253 Assert.AreEqual(2, loadedSettings.EstateBans.Length); 253 Assert.AreEqual(2, loadedSettings.EstateBans.Length);
254 Assert.AreEqual(DataTestUtil.UUID_MIN, loadedSettings.EstateBans[0].BannedUserID); 254 Assert.AreEqual(DataTestUtil.UUID_MIN, loadedSettings.EstateBans[0].BannedUserID);
@@ -290,7 +290,7 @@ namespace OpenSim.Data.Tests
290 { 290 {
291 291
292 // Letting estate store generate rows to database for us 292 // Letting estate store generate rows to database for us
293 EstateSettings originalSettings = db.LoadEstateSettings(regionId); 293 EstateSettings originalSettings = db.LoadEstateSettings(regionId, true);
294 294
295 SetEstateSettings( 295 SetEstateSettings(
296 originalSettings, 296 originalSettings,
@@ -347,7 +347,7 @@ namespace OpenSim.Data.Tests
347 db.StoreEstateSettings(originalSettings); 347 db.StoreEstateSettings(originalSettings);
348 348
349 // Loading settings to another instance variable. 349 // Loading settings to another instance variable.
350 EstateSettings loadedSettings = db.LoadEstateSettings(regionId); 350 EstateSettings loadedSettings = db.LoadEstateSettings(regionId, true);
351 351
352 // Checking that loaded values are correct. 352 // Checking that loaded values are correct.
353 ValidateEstateSettings( 353 ValidateEstateSettings(
diff --git a/OpenSim/Data/Tests/BasicGridTest.cs b/OpenSim/Data/Tests/BasicGridTest.cs
deleted file mode 100644
index df6c669..0000000
--- a/OpenSim/Data/Tests/BasicGridTest.cs
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using NUnit.Framework;
32using NUnit.Framework.SyntaxHelpers;
33using OpenMetaverse;
34
35namespace OpenSim.Data.Tests
36{
37 public class BasicGridTest
38 {
39 public IGridDataPlugin db;
40 public UUID region1, region2, region3;
41 public UUID zero = UUID.Zero;
42 public static Random random = new Random();
43
44 [TearDown]
45 public void removeAllRegions()
46 {
47 // Clean up all the regions.
48 List<RegionProfileData> regions = db.GetRegionsByName("", 100);
49 if (regions != null)
50 {
51 foreach (RegionProfileData region in regions)
52 {
53 db.DeleteProfile(region.Uuid.ToString());
54 }
55 }
56 }
57
58 public void SuperInit()
59 {
60 OpenSim.Tests.Common.TestLogging.LogToConsole();
61 region1 = UUID.Random();
62 region2 = UUID.Random();
63 region3 = UUID.Random();
64 }
65
66 protected RegionProfileData createRegion(UUID regionUUID, string regionName)
67 {
68 RegionProfileData reg = new RegionProfileData();
69 new PropertyScrambler<RegionProfileData>().Scramble(reg);
70 reg.Uuid = regionUUID;
71 reg.RegionName = regionName;
72
73 db.StoreProfile(reg);
74
75 return reg;
76 }
77
78 [Test]
79 public void T001_LoadEmpty()
80 {
81 Assert.That(db.GetProfileByUUID(region1),Is.Null);
82 Assert.That(db.GetProfileByUUID(region2),Is.Null);
83 Assert.That(db.GetProfileByUUID(region3),Is.Null);
84 Assert.That(db.GetProfileByUUID(zero),Is.Null);
85 }
86
87 [Test]
88 public void T011_AddRetrieveCompleteTest()
89 {
90 RegionProfileData newreg = createRegion(region2, "|<Goth@m Ci1y>|");
91 RegionProfileData retreg = db.GetProfileByUUID(region2);
92
93 Assert.That(retreg, Constraints.PropertyCompareConstraint(newreg).IgnoreProperty(x => x.RegionOnline));
94
95 retreg = db.GetProfileByHandle(newreg.RegionHandle);
96 Assert.That(retreg.Uuid, Is.EqualTo(region2), "Assert.That(retreg.Uuid, Is.EqualTo(region2))");
97
98 retreg = db.GetProfileByString(newreg.RegionName);
99 Assert.That(retreg.Uuid, Is.EqualTo(region2), "Assert.That(retreg.Uuid, Is.EqualTo(region2))");
100
101 RegionProfileData[] retregs = db.GetProfilesInRange(newreg.RegionLocX,newreg.RegionLocY,newreg.RegionLocX,newreg.RegionLocY);
102 Assert.That(retregs[0].Uuid, Is.EqualTo(region2), "Assert.That(retregs[0].Uuid, Is.EqualTo(region2))");
103 }
104
105 [Test]
106 public void T012_DeleteProfile()
107 {
108 createRegion(region1, "doesn't matter");
109
110 db.DeleteProfile(region1.ToString());
111 RegionProfileData retreg = db.GetProfileByUUID(region1);
112 Assert.That(retreg,Is.Null);
113 }
114
115 [Test]
116 public void T013_UpdateProfile()
117 {
118 createRegion(region2, "|<Goth@m Ci1y>|");
119
120 RegionProfileData retreg = db.GetProfileByUUID(region2);
121 retreg.regionName = "Gotham City";
122
123 db.StoreProfile(retreg);
124
125 retreg = db.GetProfileByUUID(region2);
126 Assert.That(retreg.RegionName, Is.EqualTo("Gotham City"), "Assert.That(retreg.RegionName, Is.EqualTo(\"Gotham City\"))");
127 }
128
129 [Test]
130 public void T014_RegionList()
131 {
132 createRegion(region2, "Gotham City");
133
134 RegionProfileData retreg = db.GetProfileByUUID(region2);
135 retreg.RegionName = "Gotham Town";
136 retreg.Uuid = region1;
137
138 db.StoreProfile(retreg);
139
140 retreg = db.GetProfileByUUID(region2);
141 retreg.RegionName = "Gothan Town";
142 retreg.Uuid = region3;
143
144 db.StoreProfile(retreg);
145
146 List<RegionProfileData> listreg = db.GetRegionsByName("Gotham",10);
147
148 Assert.That(listreg.Count,Is.EqualTo(2), "Assert.That(listreg.Count,Is.EqualTo(2))");
149 Assert.That(listreg[0].Uuid,Is.Not.EqualTo(listreg[1].Uuid), "Assert.That(listreg[0].Uuid,Is.Not.EqualTo(listreg[1].Uuid))");
150 Assert.That(listreg[0].Uuid, Is.EqualTo(region1) | Is.EqualTo(region2), "Assert.That(listreg[0].Uuid, Is.EqualTo(region1) | Is.EqualTo(region2))");
151 Assert.That(listreg[1].Uuid, Is.EqualTo(region1) | Is.EqualTo(region2), "Assert.That(listreg[1].Uuid, Is.EqualTo(region1) | Is.EqualTo(region2))");
152 }
153
154 [Test]
155 public void T999_StillNull()
156 {
157 Assert.That(db.GetProfileByUUID(zero), Is.Null);
158 }
159
160 protected static string RandomName()
161 {
162 StringBuilder name = new StringBuilder();
163 int size = random.Next(5,12);
164 char ch ;
165 for (int i=0; i<size; i++)
166 {
167 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
168 name.Append(ch);
169 }
170 return name.ToString();
171 }
172 }
173}
diff --git a/OpenSim/Data/Tests/BasicUserTest.cs b/OpenSim/Data/Tests/BasicUserTest.cs
deleted file mode 100644
index d3b6041..0000000
--- a/OpenSim/Data/Tests/BasicUserTest.cs
+++ /dev/null
@@ -1,703 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28// TODO: Money Transfer, Inventory Transfer and UpdateUserRegion once they exist
29
30using System;
31using System.Collections.Generic;
32using System.Text;
33using log4net.Config;
34using NUnit.Framework;
35using NUnit.Framework.SyntaxHelpers;
36using OpenMetaverse;
37using OpenSim.Framework;
38using log4net;
39using System.Reflection;
40
41namespace OpenSim.Data.Tests
42{
43 public class BasicUserTest
44 {
45 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 public IUserDataPlugin db;
47 public UUID user1;
48 public UUID user2;
49 public UUID user3;
50 public UUID user4;
51 public UUID user5;
52 public UUID webkey;
53 public UUID zero = UUID.Zero;
54 public static Random random;
55
56 public UUID agent1;
57 public UUID agent2;
58 public UUID agent3;
59 public UUID agent4;
60
61 public UUID region1;
62
63 public string fname0;
64 public string lname0;
65 public string fname1;
66 public string lname1;
67 public string fname2;
68 public string lname2;
69 public string fname3;
70 public string lname3;
71
72 public void SuperInit()
73 {
74 OpenSim.Tests.Common.TestLogging.LogToConsole();
75 random = new Random();
76 user1 = UUID.Random();
77 user2 = UUID.Random();
78 user3 = UUID.Random();
79 user4 = UUID.Random();
80 user5 = UUID.Random();
81 agent1 = UUID.Random();
82 agent2 = UUID.Random();
83 agent3 = UUID.Random();
84 agent4 = UUID.Random();
85 webkey = UUID.Random();
86 region1 = UUID.Random();
87 fname0 = RandomName();
88 lname0 = RandomName();
89 fname1 = RandomName();
90 lname1 = RandomName();
91 fname2 = RandomName();
92 lname2 = RandomName();
93 fname3 = RandomName();
94 lname3 = RandomName();
95 }
96
97 [Test]
98 public void T001_LoadEmpty()
99 {
100 Assert.That(db.GetUserByUUID(zero), Is.Null);
101 Assert.That(db.GetUserByUUID(user1), Is.Null);
102 Assert.That(db.GetUserByUUID(user2), Is.Null);
103 Assert.That(db.GetUserByUUID(user3), Is.Null);
104 Assert.That(db.GetUserByUUID(UUID.Random()), Is.Null);
105
106 Assert.That(db.GetAgentByUUID(zero), Is.Null);
107 Assert.That(db.GetAgentByUUID(agent1), Is.Null);
108 Assert.That(db.GetAgentByUUID(agent2), Is.Null);
109 Assert.That(db.GetAgentByUUID(agent3), Is.Null);
110 Assert.That(db.GetAgentByUUID(UUID.Random()), Is.Null);
111 }
112
113 [Test]
114 public void T010_CreateUser()
115 {
116 UserProfileData u1 = NewUser(user1,fname1,lname1);
117 UserProfileData u2 = NewUser(user2,fname2,lname2);
118 UserProfileData u3 = NewUser(user3,fname3,lname3);
119 // this is used to check whether null works here
120 u3.Email = null;
121
122 db.AddNewUserProfile(u1);
123 db.AddNewUserProfile(u2);
124 db.AddNewUserProfile(u3);
125 UserProfileData u1a = db.GetUserByUUID(user1);
126 UserProfileData u2a = db.GetUserByUUID(user2);
127 UserProfileData u3a = db.GetUserByUUID(user3);
128 Assert.That(user1,Is.EqualTo(u1a.ID), "Assert.That(user1,Is.EqualTo(u1a.ID))");
129 Assert.That(user2,Is.EqualTo(u2a.ID), "Assert.That(user2,Is.EqualTo(u2a.ID))");
130 Assert.That(user3,Is.EqualTo(u3a.ID), "Assert.That(user3,Is.EqualTo(u3a.ID))");
131
132 // and one email test
133 Assert.That(u3.Email, Is.Null);
134 }
135
136 [Test]
137 public void T011_FetchUserByName()
138 {
139 UserProfileData u1 = db.GetUserByName(fname1,lname1);
140 UserProfileData u2 = db.GetUserByName(fname2,lname2);
141 UserProfileData u3 = db.GetUserByName(fname3,lname3);
142 Assert.That(user1,Is.EqualTo(u1.ID), "Assert.That(user1,Is.EqualTo(u1.ID))");
143 Assert.That(user2,Is.EqualTo(u2.ID), "Assert.That(user2,Is.EqualTo(u2.ID))");
144 Assert.That(user3,Is.EqualTo(u3.ID), "Assert.That(user3,Is.EqualTo(u3.ID))");
145 }
146
147 [Test]
148 public void T012_UpdateUserProfile()
149 {
150 UserProfileData u1 = db.GetUserByUUID(user1);
151 Assert.That(fname1,Is.EqualTo(u1.FirstName), "Assert.That(fname1,Is.EqualTo(u1.FirstName))");
152 u1.FirstName = "Ugly";
153
154 db.UpdateUserProfile(u1);
155 Assert.That("Ugly",Is.EqualTo(u1.FirstName), "Assert.That(\"Ugly\",Is.EqualTo(u1.FirstName))");
156 }
157
158 [Test]
159 public void T013_StoreUserWebKey()
160 {
161 UserProfileData u1 = db.GetUserByUUID(user1);
162 Assert.That(u1.WebLoginKey,Is.EqualTo(zero), "Assert.That(u1.WebLoginKey,Is.EqualTo(zero))");
163 db.StoreWebLoginKey(user1, webkey);
164 u1 = db.GetUserByUUID(user1);
165 Assert.That(u1.WebLoginKey,Is.EqualTo(webkey), "Assert.That(u1.WebLoginKey,Is.EqualTo(webkey))");
166 }
167
168 [Test]
169 public void T014_ExpectedNullReferenceReturns()
170 {
171 UserProfileData u0 = NewUser(zero,fname0,lname0);
172 UserProfileData u4 = NewUser(user4,fname2,lname2);
173 db.AddNewUserProfile(u0); //UserID 0 should fail to save.
174 db.AddNewUserProfile(u4); //The first name and last name are already in use (from T010), so this should fail too
175 Assert.That(db.GetUserByUUID(zero),Is.Null);
176 Assert.That(db.GetUserByUUID(user4),Is.Null);
177 }
178
179 [Test]
180 public void T015_UserPersistency()
181 {
182 UserProfileData u = new UserProfileData();
183 UUID id = user5;
184 string fname = RandomName();
185 string lname = RandomName();
186 string email = RandomName();
187 string passhash = RandomName();
188 string passsalt = RandomName();
189 UUID homeregion = UUID.Random();
190 UUID webloginkey = UUID.Random();
191 uint homeregx = (uint) random.Next();
192 uint homeregy = (uint) random.Next();
193 Vector3 homeloc
194 = new Vector3(
195 (float)Math.Round(random.NextDouble(), 5),
196 (float)Math.Round(random.NextDouble(), 5),
197 (float)Math.Round(random.NextDouble(), 5));
198 Vector3 homelookat
199 = new Vector3(
200 (float)Math.Round(random.NextDouble(), 5),
201 (float)Math.Round(random.NextDouble(), 5),
202 (float)Math.Round(random.NextDouble(), 5));
203 int created = random.Next();
204 int lastlogin = random.Next();
205 string userinvuri = RandomName();
206 string userasseturi = RandomName();
207 uint candomask = (uint) random.Next();
208 uint wantdomask = (uint) random.Next();
209 string abouttext = RandomName();
210 string flabouttext = RandomName();
211 UUID image = UUID.Random();
212 UUID firstimage = UUID.Random();
213 UserAgentData agent = NewAgent(id,UUID.Random());
214 int userflags = random.Next();
215 int godlevel = random.Next();
216 string customtype = RandomName();
217 UUID partner = UUID.Random();
218
219 //HomeRegionX and HomeRegionY must only use 24 bits
220 homeregx = ((homeregx << 8) >> 8);
221 homeregy = ((homeregy << 8) >> 8);
222
223 u.ID = id;
224 u.WebLoginKey = webloginkey;
225 u.HomeRegionID = homeregion;
226 u.FirstName = fname;
227 u.SurName = lname;
228 u.Email = email;
229 u.PasswordHash = passhash;
230 u.PasswordSalt = passsalt;
231 u.HomeRegionX = homeregx;
232 u.HomeRegionY = homeregy;
233 ulong homereg = u.HomeRegion;
234 u.HomeLocation = homeloc;
235 u.HomeLookAt = homelookat;
236 u.Created = created;
237 u.LastLogin = lastlogin;
238 u.UserInventoryURI = userinvuri;
239 u.UserAssetURI = userasseturi;
240 u.CanDoMask = candomask;
241 u.WantDoMask = wantdomask;
242 u.AboutText = abouttext;
243 u.FirstLifeAboutText = flabouttext;
244 u.Image = image;
245 u.FirstLifeImage = firstimage;
246 u.CurrentAgent = agent;
247 u.UserFlags = userflags;
248 u.GodLevel = godlevel;
249 u.CustomType = customtype;
250 u.Partner = partner;
251
252 db.AddNewUserProfile(u);
253 UserProfileData u1a = db.GetUserByUUID(id);
254 Assert.That(u1a,Is.Not.Null);
255 Assert.That(id,Is.EqualTo(u1a.ID), "Assert.That(id,Is.EqualTo(u1a.ID))");
256 Assert.That(homeregion,Is.EqualTo(u1a.HomeRegionID), "Assert.That(homeregion,Is.EqualTo(u1a.HomeRegionID))");
257 Assert.That(webloginkey,Is.EqualTo(u1a.WebLoginKey), "Assert.That(webloginkey,Is.EqualTo(u1a.WebLoginKey))");
258 Assert.That(fname,Is.EqualTo(u1a.FirstName), "Assert.That(fname,Is.EqualTo(u1a.FirstName))");
259 Assert.That(lname,Is.EqualTo(u1a.SurName), "Assert.That(lname,Is.EqualTo(u1a.SurName))");
260 Assert.That(email,Is.EqualTo(u1a.Email), "Assert.That(email,Is.EqualTo(u1a.Email))");
261 Assert.That(passhash,Is.EqualTo(u1a.PasswordHash), "Assert.That(passhash,Is.EqualTo(u1a.PasswordHash))");
262 Assert.That(passsalt,Is.EqualTo(u1a.PasswordSalt), "Assert.That(passsalt,Is.EqualTo(u1a.PasswordSalt))");
263 Assert.That(homeregx,Is.EqualTo(u1a.HomeRegionX), "Assert.That(homeregx,Is.EqualTo(u1a.HomeRegionX))");
264 Assert.That(homeregy,Is.EqualTo(u1a.HomeRegionY), "Assert.That(homeregy,Is.EqualTo(u1a.HomeRegionY))");
265 Assert.That(homereg,Is.EqualTo(u1a.HomeRegion), "Assert.That(homereg,Is.EqualTo(u1a.HomeRegion))");
266 Assert.That(homeloc,Is.EqualTo(u1a.HomeLocation), "Assert.That(homeloc,Is.EqualTo(u1a.HomeLocation))");
267 Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt), "Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt))");
268 Assert.That(created,Is.EqualTo(u1a.Created), "Assert.That(created,Is.EqualTo(u1a.Created))");
269 Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin), "Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin))");
270 Assert.That(userinvuri,Is.EqualTo(u1a.UserInventoryURI), "Assert.That(userinvuri,Is.EqualTo(u1a.UserInventoryURI))");
271 Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI), "Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI))");
272 Assert.That(candomask,Is.EqualTo(u1a.CanDoMask), "Assert.That(candomask,Is.EqualTo(u1a.CanDoMask))");
273 Assert.That(wantdomask,Is.EqualTo(u1a.WantDoMask), "Assert.That(wantdomask,Is.EqualTo(u1a.WantDoMask))");
274 Assert.That(abouttext,Is.EqualTo(u1a.AboutText), "Assert.That(abouttext,Is.EqualTo(u1a.AboutText))");
275 Assert.That(flabouttext,Is.EqualTo(u1a.FirstLifeAboutText), "Assert.That(flabouttext,Is.EqualTo(u1a.FirstLifeAboutText))");
276 Assert.That(image,Is.EqualTo(u1a.Image), "Assert.That(image,Is.EqualTo(u1a.Image))");
277 Assert.That(firstimage,Is.EqualTo(u1a.FirstLifeImage), "Assert.That(firstimage,Is.EqualTo(u1a.FirstLifeImage))");
278 Assert.That(u1a.CurrentAgent,Is.Null);
279 Assert.That(userflags,Is.EqualTo(u1a.UserFlags), "Assert.That(userflags,Is.EqualTo(u1a.UserFlags))");
280 Assert.That(godlevel,Is.EqualTo(u1a.GodLevel), "Assert.That(godlevel,Is.EqualTo(u1a.GodLevel))");
281 Assert.That(customtype,Is.EqualTo(u1a.CustomType), "Assert.That(customtype,Is.EqualTo(u1a.CustomType))");
282 Assert.That(partner,Is.EqualTo(u1a.Partner), "Assert.That(partner,Is.EqualTo(u1a.Partner))");
283 }
284
285 [Test]
286 public void T016_UserUpdatePersistency()
287 {
288 UUID id = user5;
289 UserProfileData u = db.GetUserByUUID(id);
290 string fname = RandomName();
291 string lname = RandomName();
292 string email = RandomName();
293 string passhash = RandomName();
294 string passsalt = RandomName();
295 UUID homeregionid = UUID.Random();
296 UUID webloginkey = UUID.Random();
297 uint homeregx = (uint) random.Next();
298 uint homeregy = (uint) random.Next();
299 Vector3 homeloc = new Vector3((float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5));
300 Vector3 homelookat = new Vector3((float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5));
301 int created = random.Next();
302 int lastlogin = random.Next();
303 string userinvuri = RandomName();
304 string userasseturi = RandomName();
305 uint candomask = (uint) random.Next();
306 uint wantdomask = (uint) random.Next();
307 string abouttext = RandomName();
308 string flabouttext = RandomName();
309 UUID image = UUID.Random();
310 UUID firstimage = UUID.Random();
311 UserAgentData agent = NewAgent(id,UUID.Random());
312 int userflags = random.Next();
313 int godlevel = random.Next();
314 string customtype = RandomName();
315 UUID partner = UUID.Random();
316
317 //HomeRegionX and HomeRegionY must only use 24 bits
318 homeregx = ((homeregx << 8) >> 8);
319 homeregy = ((homeregy << 8) >> 8);
320
321 u.WebLoginKey = webloginkey;
322 u.HomeRegionID = homeregionid;
323 u.FirstName = fname;
324 u.SurName = lname;
325 u.Email = email;
326 u.PasswordHash = passhash;
327 u.PasswordSalt = passsalt;
328 u.HomeRegionX = homeregx;
329 u.HomeRegionY = homeregy;
330 ulong homereg = u.HomeRegion;
331 u.HomeLocation = homeloc;
332 u.HomeLookAt = homelookat;
333 u.Created = created;
334 u.LastLogin = lastlogin;
335 u.UserInventoryURI = userinvuri;
336 u.UserAssetURI = userasseturi;
337 u.CanDoMask = candomask;
338 u.WantDoMask = wantdomask;
339 u.AboutText = abouttext;
340 u.FirstLifeAboutText = flabouttext;
341 u.Image = image;
342 u.FirstLifeImage = firstimage;
343 u.CurrentAgent = agent;
344 u.UserFlags = userflags;
345 u.GodLevel = godlevel;
346 u.CustomType = customtype;
347 u.Partner = partner;
348
349 db.UpdateUserProfile(u);
350 UserProfileData u1a = db.GetUserByUUID(id);
351 Assert.That(u1a,Is.Not.Null);
352 Assert.That(id,Is.EqualTo(u1a.ID), "Assert.That(id,Is.EqualTo(u1a.ID))");
353 Assert.That(homeregionid,Is.EqualTo(u1a.HomeRegionID), "Assert.That(homeregionid,Is.EqualTo(u1a.HomeRegionID))");
354 Assert.That(webloginkey,Is.EqualTo(u1a.WebLoginKey), "Assert.That(webloginkey,Is.EqualTo(u1a.WebLoginKey))");
355 Assert.That(fname,Is.EqualTo(u1a.FirstName), "Assert.That(fname,Is.EqualTo(u1a.FirstName))");
356 Assert.That(lname,Is.EqualTo(u1a.SurName), "Assert.That(lname,Is.EqualTo(u1a.SurName))");
357 Assert.That(email,Is.EqualTo(u1a.Email), "Assert.That(email,Is.EqualTo(u1a.Email))");
358 Assert.That(passhash,Is.EqualTo(u1a.PasswordHash), "Assert.That(passhash,Is.EqualTo(u1a.PasswordHash))");
359 Assert.That(passsalt,Is.EqualTo(u1a.PasswordSalt), "Assert.That(passsalt,Is.EqualTo(u1a.PasswordSalt))");
360 Assert.That(homereg,Is.EqualTo(u1a.HomeRegion), "Assert.That(homereg,Is.EqualTo(u1a.HomeRegion))");
361 Assert.That(homeregx,Is.EqualTo(u1a.HomeRegionX), "Assert.That(homeregx,Is.EqualTo(u1a.HomeRegionX))");
362 Assert.That(homeregy,Is.EqualTo(u1a.HomeRegionY), "Assert.That(homeregy,Is.EqualTo(u1a.HomeRegionY))");
363 Assert.That(homereg,Is.EqualTo(u1a.HomeRegion), "Assert.That(homereg,Is.EqualTo(u1a.HomeRegion))");
364 Assert.That(homeloc,Is.EqualTo(u1a.HomeLocation), "Assert.That(homeloc,Is.EqualTo(u1a.HomeLocation))");
365 Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt), "Assert.That(homelookat,Is.EqualTo(u1a.HomeLookAt))");
366 Assert.That(created,Is.EqualTo(u1a.Created), "Assert.That(created,Is.EqualTo(u1a.Created))");
367 Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin), "Assert.That(lastlogin,Is.EqualTo(u1a.LastLogin))");
368 Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI), "Assert.That(userasseturi,Is.EqualTo(u1a.UserAssetURI))");
369 Assert.That(candomask,Is.EqualTo(u1a.CanDoMask), "Assert.That(candomask,Is.EqualTo(u1a.CanDoMask))");
370 Assert.That(wantdomask,Is.EqualTo(u1a.WantDoMask), "Assert.That(wantdomask,Is.EqualTo(u1a.WantDoMask))");
371 Assert.That(abouttext,Is.EqualTo(u1a.AboutText), "Assert.That(abouttext,Is.EqualTo(u1a.AboutText))");
372 Assert.That(flabouttext,Is.EqualTo(u1a.FirstLifeAboutText), "Assert.That(flabouttext,Is.EqualTo(u1a.FirstLifeAboutText))");
373 Assert.That(image,Is.EqualTo(u1a.Image), "Assert.That(image,Is.EqualTo(u1a.Image))");
374 Assert.That(firstimage,Is.EqualTo(u1a.FirstLifeImage), "Assert.That(firstimage,Is.EqualTo(u1a.FirstLifeImage))");
375 Assert.That(u1a.CurrentAgent,Is.Null);
376 Assert.That(userflags,Is.EqualTo(u1a.UserFlags), "Assert.That(userflags,Is.EqualTo(u1a.UserFlags))");
377 Assert.That(godlevel,Is.EqualTo(u1a.GodLevel), "Assert.That(godlevel,Is.EqualTo(u1a.GodLevel))");
378 Assert.That(customtype,Is.EqualTo(u1a.CustomType), "Assert.That(customtype,Is.EqualTo(u1a.CustomType))");
379 Assert.That(partner,Is.EqualTo(u1a.Partner), "Assert.That(partner,Is.EqualTo(u1a.Partner))");
380 }
381
382 [Test]
383 public void T017_UserUpdateRandomPersistency()
384 {
385 UUID id = user5;
386 UserProfileData u = db.GetUserByUUID(id);
387 new PropertyScrambler<UserProfileData>().DontScramble(x=>x.ID).Scramble(u);
388
389 db.UpdateUserProfile(u);
390 UserProfileData u1a = db.GetUserByUUID(id);
391 Assert.That(u1a, Constraints.PropertyCompareConstraint(u)
392 .IgnoreProperty(x=>x.HomeRegionX)
393 .IgnoreProperty(x=>x.HomeRegionY)
394 );
395 }
396
397 [Test]
398 public void T020_CreateAgent()
399 {
400 UserAgentData a1 = NewAgent(user1,agent1);
401 UserAgentData a2 = NewAgent(user2,agent2);
402 UserAgentData a3 = NewAgent(user3,agent3);
403 db.AddNewUserAgent(a1);
404 db.AddNewUserAgent(a2);
405 db.AddNewUserAgent(a3);
406 UserAgentData a1a = db.GetAgentByUUID(user1);
407 UserAgentData a2a = db.GetAgentByUUID(user2);
408 UserAgentData a3a = db.GetAgentByUUID(user3);
409 Assert.That(agent1,Is.EqualTo(a1a.SessionID), "Assert.That(agent1,Is.EqualTo(a1a.SessionID))");
410 Assert.That(user1,Is.EqualTo(a1a.ProfileID), "Assert.That(user1,Is.EqualTo(a1a.ProfileID))");
411 Assert.That(agent2,Is.EqualTo(a2a.SessionID), "Assert.That(agent2,Is.EqualTo(a2a.SessionID))");
412 Assert.That(user2,Is.EqualTo(a2a.ProfileID), "Assert.That(user2,Is.EqualTo(a2a.ProfileID))");
413 Assert.That(agent3,Is.EqualTo(a3a.SessionID), "Assert.That(agent3,Is.EqualTo(a3a.SessionID))");
414 Assert.That(user3,Is.EqualTo(a3a.ProfileID), "Assert.That(user3,Is.EqualTo(a3a.ProfileID))");
415 }
416
417 [Test]
418 public void T021_FetchAgentByName()
419 {
420 String name3 = fname3 + " " + lname3;
421 UserAgentData a2 = db.GetAgentByName(fname2,lname2);
422 UserAgentData a3 = db.GetAgentByName(name3);
423 Assert.That(user2,Is.EqualTo(a2.ProfileID), "Assert.That(user2,Is.EqualTo(a2.ProfileID))");
424 Assert.That(user3,Is.EqualTo(a3.ProfileID), "Assert.That(user3,Is.EqualTo(a3.ProfileID))");
425 }
426
427 [Test]
428 public void T022_ExceptionalCases()
429 {
430 UserAgentData a0 = NewAgent(user4,zero);
431 UserAgentData a4 = NewAgent(zero,agent4);
432 db.AddNewUserAgent(a0);
433 db.AddNewUserAgent(a4);
434
435 Assert.That(db.GetAgentByUUID(user4),Is.Null);
436 Assert.That(db.GetAgentByUUID(zero),Is.Null);
437 }
438
439 [Test]
440 public void T023_AgentPersistency()
441 {
442 UUID user = user4;
443 UUID agent = agent4;
444 UUID secureagent = UUID.Random();
445 string agentip = RandomName();
446 uint agentport = (uint)random.Next();
447 bool agentonline = (random.NextDouble() > 0.5);
448 int logintime = random.Next();
449 int logouttime = random.Next();
450 UUID regionid = UUID.Random();
451 ulong regionhandle = (ulong) random.Next();
452 Vector3 currentpos = new Vector3((float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5));
453 Vector3 currentlookat = new Vector3((float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5));
454 UUID orgregionid = UUID.Random();
455
456 UserAgentData a = new UserAgentData();
457 a.ProfileID = user;
458 a.SessionID = agent;
459 a.SecureSessionID = secureagent;
460 a.AgentIP = agentip;
461 a.AgentPort = agentport;
462 a.AgentOnline = agentonline;
463 a.LoginTime = logintime;
464 a.LogoutTime = logouttime;
465 a.Region = regionid;
466 a.Handle = regionhandle;
467 a.Position = currentpos;
468 a.LookAt = currentlookat;
469 a.InitialRegion = orgregionid;
470
471 db.AddNewUserAgent(a);
472
473 UserAgentData a1 = db.GetAgentByUUID(user4);
474 Assert.That(user,Is.EqualTo(a1.ProfileID), "Assert.That(user,Is.EqualTo(a1.ProfileID))");
475 Assert.That(agent,Is.EqualTo(a1.SessionID), "Assert.That(agent,Is.EqualTo(a1.SessionID))");
476 Assert.That(secureagent,Is.EqualTo(a1.SecureSessionID), "Assert.That(secureagent,Is.EqualTo(a1.SecureSessionID))");
477 Assert.That(agentip,Is.EqualTo(a1.AgentIP), "Assert.That(agentip,Is.EqualTo(a1.AgentIP))");
478 Assert.That(agentport,Is.EqualTo(a1.AgentPort), "Assert.That(agentport,Is.EqualTo(a1.AgentPort))");
479 Assert.That(agentonline,Is.EqualTo(a1.AgentOnline), "Assert.That(agentonline,Is.EqualTo(a1.AgentOnline))");
480 Assert.That(logintime,Is.EqualTo(a1.LoginTime), "Assert.That(logintime,Is.EqualTo(a1.LoginTime))");
481 Assert.That(logouttime,Is.EqualTo(a1.LogoutTime), "Assert.That(logouttime,Is.EqualTo(a1.LogoutTime))");
482 Assert.That(regionid,Is.EqualTo(a1.Region), "Assert.That(regionid,Is.EqualTo(a1.Region))");
483 Assert.That(regionhandle,Is.EqualTo(a1.Handle), "Assert.That(regionhandle,Is.EqualTo(a1.Handle))");
484 Assert.That(currentpos,Is.EqualTo(a1.Position), "Assert.That(currentpos,Is.EqualTo(a1.Position))");
485 Assert.That(currentlookat,Is.EqualTo(a1.LookAt), "Assert.That(currentlookat,Is.EqualTo(a1.LookAt))");
486 }
487
488 [Test]
489 public void T030_CreateFriendList()
490 {
491 Dictionary<UUID, uint> perms = new Dictionary<UUID,uint>();
492 Dictionary<UUID, int> friends = new Dictionary<UUID,int>();
493 uint temp;
494 int tempu1, tempu2;
495 db.AddNewUserFriend(user1,user2, 1);
496 db.AddNewUserFriend(user1,user3, 2);
497 db.AddNewUserFriend(user1,user2, 4);
498 List<FriendListItem> fl1 = db.GetUserFriendList(user1);
499 Assert.That(fl1.Count,Is.EqualTo(2), "Assert.That(fl1.Count,Is.EqualTo(2))");
500 perms.Add(user2,1);
501 perms.Add(user3,2);
502 for (int i = 0; i < fl1.Count; i++)
503 {
504 Assert.That(user1,Is.EqualTo(fl1[i].FriendListOwner), "Assert.That(user1,Is.EqualTo(fl1[i].FriendListOwner))");
505 friends.Add(fl1[i].Friend,1);
506 temp = perms[fl1[i].Friend];
507 Assert.That(temp,Is.EqualTo(fl1[i].FriendPerms), "Assert.That(temp,Is.EqualTo(fl1[i].FriendPerms))");
508 }
509 tempu1 = friends[user2];
510 tempu2 = friends[user3];
511 Assert.That(1,Is.EqualTo(tempu1) & Is.EqualTo(tempu2), "Assert.That(1,Is.EqualTo(tempu1) & Is.EqualTo(tempu2))");
512 }
513
514 [Test]
515 public void T031_RemoveUserFriend()
516 // user1 has 2 friends, user2 and user3.
517 {
518 List<FriendListItem> fl1 = db.GetUserFriendList(user1);
519 List<FriendListItem> fl2 = db.GetUserFriendList(user2);
520
521 Assert.That(fl1.Count,Is.EqualTo(2), "Assert.That(fl1.Count,Is.EqualTo(2))");
522 Assert.That(fl1[0].Friend,Is.EqualTo(user2) | Is.EqualTo(user3), "Assert.That(fl1[0].Friend,Is.EqualTo(user2) | Is.EqualTo(user3))");
523 Assert.That(fl2[0].Friend,Is.EqualTo(user1), "Assert.That(fl2[0].Friend,Is.EqualTo(user1))");
524 db.RemoveUserFriend(user2, user1);
525
526 fl1 = db.GetUserFriendList(user1);
527 fl2 = db.GetUserFriendList(user2);
528 Assert.That(fl1.Count,Is.EqualTo(1), "Assert.That(fl1.Count,Is.EqualTo(1))");
529 Assert.That(fl1[0].Friend, Is.EqualTo(user3), "Assert.That(fl1[0].Friend, Is.EqualTo(user3))");
530 Assert.That(fl2, Is.Empty);
531 }
532
533 [Test]
534 public void T032_UpdateFriendPerms()
535 // user1 has 1 friend, user3, who has permission 2 in T030.
536 {
537 List<FriendListItem> fl1 = db.GetUserFriendList(user1);
538 Assert.That(fl1[0].FriendPerms,Is.EqualTo(2), "Assert.That(fl1[0].FriendPerms,Is.EqualTo(2))");
539 db.UpdateUserFriendPerms(user1, user3, 4);
540
541 fl1 = db.GetUserFriendList(user1);
542 Assert.That(fl1[0].FriendPerms,Is.EqualTo(4), "Assert.That(fl1[0].FriendPerms,Is.EqualTo(4))");
543 }
544
545 [Test]
546 public void T040_UserAppearance()
547 {
548 AvatarAppearance appear = new AvatarAppearance();
549 appear.Owner = user1;
550 db.UpdateUserAppearance(user1, appear);
551 AvatarAppearance user1app = db.GetUserAppearance(user1);
552 Assert.That(user1,Is.EqualTo(user1app.Owner), "Assert.That(user1,Is.EqualTo(user1app.Owner))");
553 }
554
555 [Test]
556 public void T041_UserAppearancePersistency()
557 {
558 AvatarAppearance appear = new AvatarAppearance();
559 UUID owner = UUID.Random();
560 int serial = random.Next();
561 byte[] visualp = new byte[218];
562 random.NextBytes(visualp);
563 UUID bodyitem = UUID.Random();
564 UUID bodyasset = UUID.Random();
565 UUID skinitem = UUID.Random();
566 UUID skinasset = UUID.Random();
567 UUID hairitem = UUID.Random();
568 UUID hairasset = UUID.Random();
569 UUID eyesitem = UUID.Random();
570 UUID eyesasset = UUID.Random();
571 UUID shirtitem = UUID.Random();
572 UUID shirtasset = UUID.Random();
573 UUID pantsitem = UUID.Random();
574 UUID pantsasset = UUID.Random();
575 UUID shoesitem = UUID.Random();
576 UUID shoesasset = UUID.Random();
577 UUID socksitem = UUID.Random();
578 UUID socksasset = UUID.Random();
579 UUID jacketitem = UUID.Random();
580 UUID jacketasset = UUID.Random();
581 UUID glovesitem = UUID.Random();
582 UUID glovesasset = UUID.Random();
583 UUID ushirtitem = UUID.Random();
584 UUID ushirtasset = UUID.Random();
585 UUID upantsitem = UUID.Random();
586 UUID upantsasset = UUID.Random();
587 UUID skirtitem = UUID.Random();
588 UUID skirtasset = UUID.Random();
589 Primitive.TextureEntry texture = AvatarAppearance.GetDefaultTexture();
590 float avatarheight = (float) (Math.Round(random.NextDouble(),5));
591
592 appear.Owner = owner;
593 appear.Serial = serial;
594 appear.VisualParams = visualp;
595 appear.BodyItem = bodyitem;
596 appear.BodyAsset = bodyasset;
597 appear.SkinItem = skinitem;
598 appear.SkinAsset = skinasset;
599 appear.HairItem = hairitem;
600 appear.HairAsset = hairasset;
601 appear.EyesItem = eyesitem;
602 appear.EyesAsset = eyesasset;
603 appear.ShirtItem = shirtitem;
604 appear.ShirtAsset = shirtasset;
605 appear.PantsItem = pantsitem;
606 appear.PantsAsset = pantsasset;
607 appear.ShoesItem = shoesitem;
608 appear.ShoesAsset = shoesasset;
609 appear.SocksItem = socksitem;
610 appear.SocksAsset = socksasset;
611 appear.JacketItem = jacketitem;
612 appear.JacketAsset = jacketasset;
613 appear.GlovesItem = glovesitem;
614 appear.GlovesAsset = glovesasset;
615 appear.UnderShirtItem = ushirtitem;
616 appear.UnderShirtAsset = ushirtasset;
617 appear.UnderPantsItem = upantsitem;
618 appear.UnderPantsAsset = upantsasset;
619 appear.SkirtItem = skirtitem;
620 appear.SkirtAsset = skirtasset;
621 appear.Texture = texture;
622 appear.AvatarHeight = avatarheight;
623
624 db.UpdateUserAppearance(owner, appear);
625 AvatarAppearance app = db.GetUserAppearance(owner);
626
627 Assert.That(owner,Is.EqualTo(app.Owner), "Assert.That(owner,Is.EqualTo(app.Owner))");
628 Assert.That(serial,Is.EqualTo(app.Serial), "Assert.That(serial,Is.EqualTo(app.Serial))");
629 Assert.That(visualp,Is.EqualTo(app.VisualParams), "Assert.That(visualp,Is.EqualTo(app.VisualParams))");
630 Assert.That(bodyitem,Is.EqualTo(app.BodyItem), "Assert.That(bodyitem,Is.EqualTo(app.BodyItem))");
631 Assert.That(bodyasset,Is.EqualTo(app.BodyAsset), "Assert.That(bodyasset,Is.EqualTo(app.BodyAsset))");
632 Assert.That(skinitem,Is.EqualTo(app.SkinItem), "Assert.That(skinitem,Is.EqualTo(app.SkinItem))");
633 Assert.That(skinasset,Is.EqualTo(app.SkinAsset), "Assert.That(skinasset,Is.EqualTo(app.SkinAsset))");
634 Assert.That(hairitem,Is.EqualTo(app.HairItem), "Assert.That(hairitem,Is.EqualTo(app.HairItem))");
635 Assert.That(hairasset,Is.EqualTo(app.HairAsset), "Assert.That(hairasset,Is.EqualTo(app.HairAsset))");
636 Assert.That(eyesitem,Is.EqualTo(app.EyesItem), "Assert.That(eyesitem,Is.EqualTo(app.EyesItem))");
637 Assert.That(eyesasset,Is.EqualTo(app.EyesAsset), "Assert.That(eyesasset,Is.EqualTo(app.EyesAsset))");
638 Assert.That(shirtitem,Is.EqualTo(app.ShirtItem), "Assert.That(shirtitem,Is.EqualTo(app.ShirtItem))");
639 Assert.That(shirtasset,Is.EqualTo(app.ShirtAsset), "Assert.That(shirtasset,Is.EqualTo(app.ShirtAsset))");
640 Assert.That(pantsitem,Is.EqualTo(app.PantsItem), "Assert.That(pantsitem,Is.EqualTo(app.PantsItem))");
641 Assert.That(pantsasset,Is.EqualTo(app.PantsAsset), "Assert.That(pantsasset,Is.EqualTo(app.PantsAsset))");
642 Assert.That(shoesitem,Is.EqualTo(app.ShoesItem), "Assert.That(shoesitem,Is.EqualTo(app.ShoesItem))");
643 Assert.That(shoesasset,Is.EqualTo(app.ShoesAsset), "Assert.That(shoesasset,Is.EqualTo(app.ShoesAsset))");
644 Assert.That(socksitem,Is.EqualTo(app.SocksItem), "Assert.That(socksitem,Is.EqualTo(app.SocksItem))");
645 Assert.That(socksasset,Is.EqualTo(app.SocksAsset), "Assert.That(socksasset,Is.EqualTo(app.SocksAsset))");
646 Assert.That(jacketitem,Is.EqualTo(app.JacketItem), "Assert.That(jacketitem,Is.EqualTo(app.JacketItem))");
647 Assert.That(jacketasset,Is.EqualTo(app.JacketAsset), "Assert.That(jacketasset,Is.EqualTo(app.JacketAsset))");
648 Assert.That(glovesitem,Is.EqualTo(app.GlovesItem), "Assert.That(glovesitem,Is.EqualTo(app.GlovesItem))");
649 Assert.That(glovesasset,Is.EqualTo(app.GlovesAsset), "Assert.That(glovesasset,Is.EqualTo(app.GlovesAsset))");
650 Assert.That(ushirtitem,Is.EqualTo(app.UnderShirtItem), "Assert.That(ushirtitem,Is.EqualTo(app.UnderShirtItem))");
651 Assert.That(ushirtasset,Is.EqualTo(app.UnderShirtAsset), "Assert.That(ushirtasset,Is.EqualTo(app.UnderShirtAsset))");
652 Assert.That(upantsitem,Is.EqualTo(app.UnderPantsItem), "Assert.That(upantsitem,Is.EqualTo(app.UnderPantsItem))");
653 Assert.That(upantsasset,Is.EqualTo(app.UnderPantsAsset), "Assert.That(upantsasset,Is.EqualTo(app.UnderPantsAsset))");
654 Assert.That(skirtitem,Is.EqualTo(app.SkirtItem), "Assert.That(skirtitem,Is.EqualTo(app.SkirtItem))");
655 Assert.That(skirtasset,Is.EqualTo(app.SkirtAsset), "Assert.That(skirtasset,Is.EqualTo(app.SkirtAsset))");
656 Assert.That(texture.ToString(),Is.EqualTo(app.Texture.ToString()), "Assert.That(texture.ToString(),Is.EqualTo(app.Texture.ToString()))");
657 Assert.That(avatarheight,Is.EqualTo(app.AvatarHeight), "Assert.That(avatarheight,Is.EqualTo(app.AvatarHeight))");
658 }
659
660 [Test]
661 public void T999_StillNull()
662 {
663 Assert.That(db.GetUserByUUID(zero), Is.Null);
664 Assert.That(db.GetAgentByUUID(zero), Is.Null);
665 }
666
667 public UserProfileData NewUser(UUID id,string fname,string lname)
668 {
669 UserProfileData u = new UserProfileData();
670 u.ID = id;
671 u.FirstName = fname;
672 u.SurName = lname;
673 u.PasswordHash = "NOTAHASH";
674 u.PasswordSalt = "NOTSALT";
675 // MUST specify at least these 5 parameters or an exception is raised
676
677 return u;
678 }
679
680 public UserAgentData NewAgent(UUID user_profile, UUID agent)
681 {
682 UserAgentData a = new UserAgentData();
683 a.ProfileID = user_profile;
684 a.SessionID = agent;
685 a.SecureSessionID = UUID.Random();
686 a.AgentIP = RandomName();
687 return a;
688 }
689
690 public static string RandomName()
691 {
692 StringBuilder name = new StringBuilder();
693 int size = random.Next(5,12);
694 char ch ;
695 for (int i=0; i<size; i++)
696 {
697 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
698 name.Append(ch);
699 }
700 return name.ToString();
701 }
702 }
703}
diff --git a/OpenSim/Data/Tests/PropertyCompareConstraint.cs b/OpenSim/Data/Tests/PropertyCompareConstraint.cs
index 5b1f935..f3d41df 100644
--- a/OpenSim/Data/Tests/PropertyCompareConstraint.cs
+++ b/OpenSim/Data/Tests/PropertyCompareConstraint.cs
@@ -297,8 +297,8 @@ namespace OpenSim.Data.Tests
297 public void AssetShouldMatch() 297 public void AssetShouldMatch()
298 { 298 {
299 UUID uuid1 = UUID.Random(); 299 UUID uuid1 = UUID.Random();
300 AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); 300 AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
301 AssetBase expected = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); 301 AssetBase expected = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
302 302
303 var constraint = Constraints.PropertyCompareConstraint(expected); 303 var constraint = Constraints.PropertyCompareConstraint(expected);
304 304
@@ -309,8 +309,8 @@ namespace OpenSim.Data.Tests
309 public void AssetShouldNotMatch() 309 public void AssetShouldNotMatch()
310 { 310 {
311 UUID uuid1 = UUID.Random(); 311 UUID uuid1 = UUID.Random();
312 AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); 312 AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
313 AssetBase expected = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture); 313 AssetBase expected = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
314 314
315 var constraint = Constraints.PropertyCompareConstraint(expected); 315 var constraint = Constraints.PropertyCompareConstraint(expected);
316 316
@@ -321,8 +321,8 @@ namespace OpenSim.Data.Tests
321 public void AssetShouldNotMatch2() 321 public void AssetShouldNotMatch2()
322 { 322 {
323 UUID uuid1 = UUID.Random(); 323 UUID uuid1 = UUID.Random();
324 AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); 324 AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
325 AssetBase expected = new AssetBase(uuid1, "asset two", (sbyte)AssetType.Texture); 325 AssetBase expected = new AssetBase(uuid1, "asset two", (sbyte)AssetType.Texture, UUID.Zero.ToString());
326 326
327 var constraint = Constraints.PropertyCompareConstraint(expected); 327 var constraint = Constraints.PropertyCompareConstraint(expected);
328 328
diff --git a/OpenSim/Data/Tests/PropertyScrambler.cs b/OpenSim/Data/Tests/PropertyScrambler.cs
index c968364..132294a 100644
--- a/OpenSim/Data/Tests/PropertyScrambler.cs
+++ b/OpenSim/Data/Tests/PropertyScrambler.cs
@@ -165,7 +165,7 @@ namespace OpenSim.Data.Tests
165 [Test] 165 [Test]
166 public void TestScramble() 166 public void TestScramble()
167 { 167 {
168 AssetBase actual = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture); 168 AssetBase actual = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture, UUID.Zero.ToString());
169 new PropertyScrambler<AssetBase>().Scramble(actual); 169 new PropertyScrambler<AssetBase>().Scramble(actual);
170 } 170 }
171 171
@@ -173,7 +173,7 @@ namespace OpenSim.Data.Tests
173 public void DontScramble() 173 public void DontScramble()
174 { 174 {
175 UUID uuid = UUID.Random(); 175 UUID uuid = UUID.Random();
176 AssetBase asset = new AssetBase(uuid, "asset", (sbyte)AssetType.Texture); 176 AssetBase asset = new AssetBase(uuid, "asset", (sbyte)AssetType.Texture, UUID.Zero.ToString());
177 new PropertyScrambler<AssetBase>() 177 new PropertyScrambler<AssetBase>()
178 .DontScramble(x => x.Metadata) 178 .DontScramble(x => x.Metadata)
179 .DontScramble(x => x.FullID) 179 .DontScramble(x => x.FullID)
diff --git a/OpenSim/Data/UserDataBase.cs b/OpenSim/Data/UserDataBase.cs
deleted file mode 100644
index 3d370da..0000000
--- a/OpenSim/Data/UserDataBase.cs
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenSim.Framework;
32
33namespace OpenSim.Data
34{
35 public abstract class UserDataBase : IUserDataPlugin
36 {
37 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
38
39 // private Dictionary<UUID, AvatarAppearance> aplist = new Dictionary<UUID, AvatarAppearance>();
40
41 public abstract UserProfileData GetUserByUUID(UUID user);
42 public abstract UserProfileData GetUserByName(string fname, string lname);
43 public abstract UserAgentData GetAgentByUUID(UUID user);
44 public abstract UserAgentData GetAgentByName(string name);
45 public abstract UserAgentData GetAgentByName(string fname, string lname);
46 public UserProfileData GetUserByUri(Uri uri) { return null; }
47 public abstract void StoreWebLoginKey(UUID agentID, UUID webLoginKey);
48 public abstract void AddNewUserProfile(UserProfileData user);
49
50 public virtual void AddTemporaryUserProfile(UserProfileData userProfile)
51 {
52 // Deliberately blank - database plugins shouldn't store temporary profiles.
53 }
54
55 public abstract bool UpdateUserProfile(UserProfileData user);
56 public abstract void AddNewUserAgent(UserAgentData agent);
57 public abstract void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms);
58 public abstract void RemoveUserFriend(UUID friendlistowner, UUID friend);
59 public abstract void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms);
60 public abstract List<FriendListItem> GetUserFriendList(UUID friendlistowner);
61 public abstract Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids);
62 public abstract bool MoneyTransferRequest(UUID from, UUID to, uint amount);
63 public abstract bool InventoryTransferRequest(UUID from, UUID to, UUID inventory);
64 public abstract List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query);
65 public abstract AvatarAppearance GetUserAppearance(UUID user);
66 public abstract void UpdateUserAppearance(UUID user, AvatarAppearance appearance);
67 // public virtual AvatarAppearance GetUserAppearance(UUID user) {
68 // AvatarAppearance aa = null;
69 // try {
70 // aa = aplist[user];
71 // m_log.Info("[APPEARANCE] Found appearance for " + user.ToString() + aa.ToString());
72 // } catch (System.Collections.Generic.KeyNotFoundException e) {
73 // m_log.Info("[APPEARANCE] No appearance found for " + user.ToString());
74 // }
75 // return aa;
76 // }
77 // public virtual void UpdateUserAppearance(UUID user, AvatarAppearance appearance) {
78 // aplist[user] = appearance;
79 // m_log.Info("[APPEARANCE] Setting appearance for " + user.ToString() + appearance.ToString());
80 // }
81 public abstract void ResetAttachments(UUID userID);
82
83 public abstract void LogoutUsers(UUID regionID);
84
85 public abstract string Version {get;}
86 public abstract string Name {get;}
87 public abstract void Initialise(string connect);
88 public abstract void Initialise();
89 public abstract void Dispose();
90 }
91}
diff --git a/OpenSim/Data/MySQL/Tests/MySQLGridTest.cs b/OpenSim/Server/Handlers/Simulation/Utils.cs
index 8272316..ed379da 100644
--- a/OpenSim/Data/MySQL/Tests/MySQLGridTest.cs
+++ b/OpenSim/Server/Handlers/Simulation/Utils.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -26,69 +26,78 @@
26 */ 26 */
27 27
28using System; 28using System;
29using NUnit.Framework; 29using System.Collections.Generic;
30using OpenSim.Data.Tests;
31using log4net;
32using System.Reflection; 30using System.Reflection;
33using OpenSim.Tests.Common;
34using MySql.Data.MySqlClient;
35 31
36namespace OpenSim.Data.MySQL.Tests 32using OpenMetaverse;
33using OpenMetaverse.StructuredData;
34
35using log4net;
36
37namespace OpenSim.Server.Handlers.Simulation
37{ 38{
38 [TestFixture, DatabaseTest] 39 public class Utils
39 public class MySQLGridTest : BasicGridTest
40 { 40 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 42
43 public string file; 43 /// <summary>
44 public MySQLManager database; 44 /// Extract the param from an uri.
45 public string connect = "Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;Pooling=false;"; 45 /// </summary>
46 46 /// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/handle/release</param>
47 [TestFixtureSetUp] 47 /// <param name="uri">uuid on uuid field</param>
48 public void Init() 48 /// <param name="action">optional action</param>
49 public static bool GetParams(string uri, out UUID uuid, out UUID regionID, out string action)
49 { 50 {
50 SuperInit(); 51 uuid = UUID.Zero;
51 // If we manage to connect to the database with the user 52 regionID = UUID.Zero;
52 // and password above it is our test database, and run 53 action = "";
53 // these tests. If anything goes wrong, ignore these 54
54 // tests. 55 uri = uri.Trim(new char[] { '/' });
55 try 56 string[] parts = uri.Split('/');
57 if (parts.Length <= 1)
56 { 58 {
57 database = new MySQLManager(connect); 59 return false;
58 db = new MySQLGridData();
59 db.Initialise(connect);
60 } 60 }
61 catch (Exception e) 61 else
62 { 62 {
63 m_log.Error("Exception {0}", e); 63 if (!UUID.TryParse(parts[1], out uuid))
64 Assert.Ignore(); 64 return false;
65 }
66 65
67 // This actually does the roll forward assembly stuff 66 if (parts.Length >= 3)
68 Assembly assem = GetType().Assembly; 67 UUID.TryParse(parts[2], out regionID);
68 if (parts.Length >= 4)
69 action = parts[3];
69 70
70 using (MySqlConnection dbcon = new MySqlConnection(connect)) 71 return true;
71 {
72 dbcon.Open();
73 Migration m = new Migration(dbcon, assem, "AssetStore");
74 m.Update();
75 } 72 }
76 } 73 }
77 74
78 [TestFixtureTearDown] 75 public static OSDMap GetOSDMap(string data)
79 public void Cleanup()
80 { 76 {
81 m_log.Warn("Cleaning up."); 77 OSDMap args = null;
82 if (db != null) 78 try
83 { 79 {
84 db.Dispose(); 80 OSD buffer;
81 // We should pay attention to the content-type, but let's assume we know it's Json
82 buffer = OSDParser.DeserializeJson(data);
83 if (buffer.Type == OSDType.Map)
84 {
85 args = (OSDMap)buffer;
86 return args;
87 }
88 else
89 {
90 // uh?
91 m_log.Debug(("[REST COMMS]: Got OSD of unexpected type " + buffer.Type.ToString()));
92 return null;
93 }
85 } 94 }
86 // if a new table is added, it has to be dropped here 95 catch (Exception ex)
87 if (database != null)
88 { 96 {
89 database.ExecuteSql("drop table migrations"); 97 m_log.Debug("[REST COMMS]: exception on parse of REST message " + ex.Message);
90 database.ExecuteSql("drop table regions"); 98 return null;
91 } 99 }
92 } 100 }
101
93 } 102 }
94} 103}