aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MySQL
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/MySQL')
-rw-r--r--OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs56
-rw-r--r--OpenSim/Data/MySQL/MySQLAssetData.cs367
-rw-r--r--OpenSim/Data/MySQL/MySQLAuthenticationData.cs231
-rw-r--r--OpenSim/Data/MySQL/MySQLAvatarData.cs68
-rw-r--r--OpenSim/Data/MySQL/MySQLEstateData.cs600
-rw-r--r--OpenSim/Data/MySQL/MySQLFSAssetData.cs433
-rw-r--r--OpenSim/Data/MySQL/MySQLFramework.cs121
-rw-r--r--OpenSim/Data/MySQL/MySQLFriendsData.cs86
-rw-r--r--OpenSim/Data/MySQL/MySQLGenericTableHandler.cs421
-rw-r--r--OpenSim/Data/MySQL/MySQLGridUserData.cs64
-rw-r--r--OpenSim/Data/MySQL/MySQLGroupsData.cs483
-rw-r--r--OpenSim/Data/MySQL/MySQLHGTravelData.cs80
-rw-r--r--OpenSim/Data/MySQL/MySQLInventoryData.cs916
-rw-r--r--OpenSim/Data/MySQL/MySQLMigrations.cs83
-rw-r--r--OpenSim/Data/MySQL/MySQLMuteListData.cs67
-rw-r--r--OpenSim/Data/MySQL/MySQLOfflineIMData.cs59
-rw-r--r--OpenSim/Data/MySQL/MySQLPresenceData.cs122
-rw-r--r--OpenSim/Data/MySQL/MySQLRaw.cs197
-rw-r--r--OpenSim/Data/MySQL/MySQLRegionData.cs421
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs2337
-rw-r--r--OpenSim/Data/MySQL/MySQLUserAccountData.cs105
-rw-r--r--OpenSim/Data/MySQL/MySQLUserProfilesData.cs1030
-rw-r--r--OpenSim/Data/MySQL/MySQLXAssetData.cs522
-rw-r--r--OpenSim/Data/MySQL/MySQLXInventoryData.cs339
-rw-r--r--OpenSim/Data/MySQL/Properties/AssemblyInfo.cs65
-rw-r--r--OpenSim/Data/MySQL/Resources/AgentPrefs.migrations18
-rw-r--r--OpenSim/Data/MySQL/Resources/AssetStore.migrations21
-rw-r--r--OpenSim/Data/MySQL/Resources/AuthStore.migrations24
-rw-r--r--OpenSim/Data/MySQL/Resources/Avatar.migrations13
-rw-r--r--OpenSim/Data/MySQL/Resources/EstateStore.migrations71
-rw-r--r--OpenSim/Data/MySQL/Resources/FSAssetStore.migrations18
-rw-r--r--OpenSim/Data/MySQL/Resources/FriendsStore.migrations14
-rw-r--r--OpenSim/Data/MySQL/Resources/GridStore.migrations52
-rw-r--r--OpenSim/Data/MySQL/Resources/GridUserStore.migrations19
-rw-r--r--OpenSim/Data/MySQL/Resources/HGTravelStore.migrations17
-rw-r--r--OpenSim/Data/MySQL/Resources/IM_Store.migrations16
-rw-r--r--OpenSim/Data/MySQL/Resources/InventoryStore.migrations42
-rw-r--r--OpenSim/Data/MySQL/Resources/LogStore.migrations13
-rw-r--r--OpenSim/Data/MySQL/Resources/MuteListStore.migrations16
-rw-r--r--OpenSim/Data/MySQL/Resources/Presence.migrations16
-rw-r--r--OpenSim/Data/MySQL/Resources/RegionStore.migrations469
-rw-r--r--OpenSim/Data/MySQL/Resources/UserAccount.migrations31
-rw-r--r--OpenSim/Data/MySQL/Resources/UserProfiles.migrations86
-rw-r--r--OpenSim/Data/MySQL/Resources/XAssetStore.migrations32
-rw-r--r--OpenSim/Data/MySQL/Resources/XMute.migrations16
-rw-r--r--OpenSim/Data/MySQL/Resources/os_groups_Store.migrations115
46 files changed, 10392 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs
new file mode 100644
index 0000000..17f1374
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs
@@ -0,0 +1,56 @@
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 MySQLAgentPreferencesData : MySQLGenericTableHandler<AgentPreferencesData>, IAgentPreferencesData
39 {
40 public MySQLAgentPreferencesData(string connectionString, string realm)
41 : base(connectionString, realm, "AgentPrefs")
42 {
43 }
44
45 public AgentPreferencesData GetPrefs(UUID agentID)
46 {
47 AgentPreferencesData[] ret = Get("PrincipalID", agentID.ToString());
48
49 if (ret.Length == 0)
50 return null;
51
52 return ret[0];
53 }
54 }
55}
56
diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs
new file mode 100644
index 0000000..8569c90
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLAssetData.cs
@@ -0,0 +1,367 @@
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 MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Data;
37
38namespace OpenSim.Data.MySQL
39{
40 /// <summary>
41 /// A MySQL Interface for the Asset Server
42 /// </summary>
43 public class MySQLAssetData : AssetDataBase
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 private string m_connectionString;
48
49 protected virtual Assembly Assembly
50 {
51 get { return GetType().Assembly; }
52 }
53
54 #region IPlugin Members
55
56 public override string Version { get { return "1.0.0.0"; } }
57
58 /// <summary>
59 /// <para>Initialises Asset interface</para>
60 /// <para>
61 /// <list type="bullet">
62 /// <item>Loads and initialises the MySQL storage plugin.</item>
63 /// <item>Warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
64 /// <item>Check for migration</item>
65 /// </list>
66 /// </para>
67 /// </summary>
68 /// <param name="connect">connect string</param>
69 public override void Initialise(string connect)
70 {
71 m_connectionString = connect;
72
73 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
74 {
75 dbcon.Open();
76 Migration m = new Migration(dbcon, Assembly, "AssetStore");
77 m.Update();
78 dbcon.Close();
79 }
80 }
81
82 public override void Initialise()
83 {
84 throw new NotImplementedException();
85 }
86
87 public override void Dispose() { }
88
89 /// <summary>
90 /// The name of this DB provider
91 /// </summary>
92 override public string Name
93 {
94 get { return "MySQL Asset storage engine"; }
95 }
96
97 #endregion
98
99 #region IAssetDataPlugin Members
100
101 /// <summary>
102 /// Fetch Asset <paramref name="assetID"/> from database
103 /// </summary>
104 /// <param name="assetID">Asset UUID to fetch</param>
105 /// <returns>Return the asset</returns>
106 /// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks>
107 override public AssetBase GetAsset(UUID assetID)
108 {
109 AssetBase asset = null;
110
111 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
112 {
113 dbcon.Open();
114
115 using (MySqlCommand cmd = new MySqlCommand(
116 "SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id",
117 dbcon))
118 {
119 cmd.Parameters.AddWithValue("?id", assetID.ToString());
120
121 try
122 {
123 using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
124 {
125 if (dbReader.Read())
126 {
127 asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString());
128 asset.Data = (byte[])dbReader["data"];
129 asset.Description = (string)dbReader["description"];
130
131 string local = dbReader["local"].ToString();
132 if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
133 asset.Local = true;
134 else
135 asset.Local = false;
136
137 asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
138 asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
139 }
140 }
141 }
142 catch (Exception e)
143 {
144 m_log.Error(
145 string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
146 }
147 }
148 dbcon.Close();
149 }
150
151 return asset;
152 }
153
154 /// <summary>
155 /// Create an asset in database, or update it if existing.
156 /// </summary>
157 /// <param name="asset">Asset UUID to create</param>
158 /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
159 override public bool StoreAsset(AssetBase asset)
160 {
161 string assetName = asset.Name;
162 if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
163 {
164 assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
165 m_log.WarnFormat(
166 "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
167 asset.Name, asset.ID, asset.Name.Length, assetName.Length);
168 }
169
170 string assetDescription = asset.Description;
171 if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
172 {
173 assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
174 m_log.WarnFormat(
175 "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
176 asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
177 }
178
179 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
180 {
181 dbcon.Open();
182 using (MySqlCommand cmd =
183 new MySqlCommand(
184 "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
185 "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
186 dbcon))
187 {
188 try
189 {
190 // create unix epoch time
191 int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
192 cmd.Parameters.AddWithValue("?id", asset.ID);
193 cmd.Parameters.AddWithValue("?name", assetName);
194 cmd.Parameters.AddWithValue("?description", assetDescription);
195 cmd.Parameters.AddWithValue("?assetType", asset.Type);
196 cmd.Parameters.AddWithValue("?local", asset.Local);
197 cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
198 cmd.Parameters.AddWithValue("?create_time", now);
199 cmd.Parameters.AddWithValue("?access_time", now);
200 cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
201 cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
202 cmd.Parameters.AddWithValue("?data", asset.Data);
203 cmd.ExecuteNonQuery();
204 dbcon.Close();
205 return true;
206 }
207 catch (Exception e)
208 {
209 m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
210 asset.FullID, asset.Name, e.Message);
211 dbcon.Close();
212 return false;
213 }
214 }
215 }
216 }
217
218 private void UpdateAccessTime(AssetBase asset)
219 {
220 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
221 {
222 dbcon.Open();
223
224 using (MySqlCommand cmd
225 = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
226 {
227 try
228 {
229 // create unix epoch time
230 int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
231 cmd.Parameters.AddWithValue("?id", asset.ID);
232 cmd.Parameters.AddWithValue("?access_time", now);
233 cmd.ExecuteNonQuery();
234 }
235 catch (Exception e)
236 {
237 m_log.Error(
238 string.Format(
239 "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
240 asset.FullID, asset.Name),
241 e);
242 }
243 }
244 dbcon.Close();
245 }
246 }
247
248 /// <summary>
249 /// Check if the assets exist in the database.
250 /// </summary>
251 /// <param name="uuidss">The assets' IDs</param>
252 /// <returns>For each asset: true if it exists, false otherwise</returns>
253 public override bool[] AssetsExist(UUID[] uuids)
254 {
255 if (uuids.Length == 0)
256 return new bool[0];
257
258 HashSet<UUID> exist = new HashSet<UUID>();
259
260 string ids = "'" + string.Join("','", uuids) + "'";
261 string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
262
263 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
264 {
265 dbcon.Open();
266 using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
267 {
268 using (MySqlDataReader dbReader = cmd.ExecuteReader())
269 {
270 while (dbReader.Read())
271 {
272 UUID id = DBGuid.FromDB(dbReader["id"]);
273 exist.Add(id);
274 }
275 }
276 }
277 dbcon.Close();
278 }
279
280 bool[] results = new bool[uuids.Length];
281 for (int i = 0; i < uuids.Length; i++)
282 results[i] = exist.Contains(uuids[i]);
283
284 return results;
285 }
286
287 /// <summary>
288 /// Returns a list of AssetMetadata objects. The list is a subset of
289 /// the entire data set offset by <paramref name="start" /> containing
290 /// <paramref name="count" /> elements.
291 /// </summary>
292 /// <param name="start">The number of results to discard from the total data set.</param>
293 /// <param name="count">The number of rows the returned list should contain.</param>
294 /// <returns>A list of AssetMetadata objects.</returns>
295 public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
296 {
297 List<AssetMetadata> retList = new List<AssetMetadata>(count);
298
299 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
300 {
301 dbcon.Open();
302
303 using (MySqlCommand cmd
304 = new MySqlCommand(
305 "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
306 dbcon))
307 {
308 cmd.Parameters.AddWithValue("?start", start);
309 cmd.Parameters.AddWithValue("?count", count);
310
311 try
312 {
313 using (MySqlDataReader dbReader = cmd.ExecuteReader())
314 {
315 while (dbReader.Read())
316 {
317 AssetMetadata metadata = new AssetMetadata();
318 metadata.Name = (string)dbReader["name"];
319 metadata.Description = (string)dbReader["description"];
320 metadata.Type = (sbyte)dbReader["assetType"];
321 metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
322 metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
323 metadata.FullID = DBGuid.FromDB(dbReader["id"]);
324 metadata.CreatorID = dbReader["CreatorID"].ToString();
325
326 // Current SHA1s are not stored/computed.
327 metadata.SHA1 = new byte[] { };
328
329 retList.Add(metadata);
330 }
331 }
332 }
333 catch (Exception e)
334 {
335 m_log.Error(
336 string.Format(
337 "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
338 start, count),
339 e);
340 }
341 }
342 dbcon.Close();
343 }
344
345 return retList;
346 }
347
348 public override bool Delete(string id)
349 {
350 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
351 {
352 dbcon.Open();
353
354 using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
355 {
356 cmd.Parameters.AddWithValue("?id", id);
357 cmd.ExecuteNonQuery();
358 }
359 dbcon.Close();
360 }
361
362 return true;
363 }
364
365 #endregion
366 }
367}
diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs
new file mode 100644
index 0000000..fef582e
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs
@@ -0,0 +1,231 @@
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 System.Data;
33using OpenMetaverse;
34using OpenSim.Framework;
35using MySql.Data.MySqlClient;
36
37namespace OpenSim.Data.MySQL
38{
39 public class MySqlAuthenticationData : MySqlFramework, IAuthenticationData
40 {
41 private string m_Realm;
42 private List<string> m_ColumnNames;
43 private int m_LastExpire;
44 // private string m_connectionString;
45
46 protected virtual Assembly Assembly
47 {
48 get { return GetType().Assembly; }
49 }
50
51 public MySqlAuthenticationData(string connectionString, string realm)
52 : base(connectionString)
53 {
54 m_Realm = realm;
55 m_connectionString = connectionString;
56
57 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
58 {
59 dbcon.Open();
60 Migration m = new Migration(dbcon, Assembly, "AuthStore");
61 m.Update();
62 dbcon.Close();
63 }
64 }
65
66 public AuthenticationData Get(UUID principalID)
67 {
68 AuthenticationData ret = new AuthenticationData();
69 ret.Data = new Dictionary<string, object>();
70
71 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
72 {
73 dbcon.Open();
74
75 using (MySqlCommand cmd
76 = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon))
77 {
78 cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
79
80 using(IDataReader result = cmd.ExecuteReader())
81 {
82 if(result.Read())
83 {
84 ret.PrincipalID = principalID;
85
86 CheckColumnNames(result);
87
88 foreach(string s in m_ColumnNames)
89 {
90 if(s == "UUID")
91 continue;
92
93 ret.Data[s] = result[s].ToString();
94 }
95
96 dbcon.Close();
97 return ret;
98 }
99 else
100 {
101 dbcon.Close();
102 return null;
103 }
104 }
105 }
106 }
107 }
108
109 private void CheckColumnNames(IDataReader result)
110 {
111 if (m_ColumnNames != null)
112 return;
113
114 List<string> columnNames = new List<string>();
115
116 DataTable schemaTable = result.GetSchemaTable();
117 foreach (DataRow row in schemaTable.Rows)
118 columnNames.Add(row["ColumnName"].ToString());
119
120 m_ColumnNames = columnNames;
121 }
122
123 public bool Store(AuthenticationData data)
124 {
125 if (data.Data.ContainsKey("UUID"))
126 data.Data.Remove("UUID");
127
128 string[] fields = new List<string>(data.Data.Keys).ToArray();
129
130 using (MySqlCommand cmd = new MySqlCommand())
131 {
132 string update = "update `"+m_Realm+"` set ";
133 bool first = true;
134 foreach (string field in fields)
135 {
136 if (!first)
137 update += ", ";
138 update += "`" + field + "` = ?"+field;
139
140 first = false;
141
142 cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
143 }
144
145 update += " where UUID = ?principalID";
146
147 cmd.CommandText = update;
148 cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
149
150 if (ExecuteNonQuery(cmd) < 1)
151 {
152 string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
153 String.Join("`, `", fields) +
154 "`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
155
156 cmd.CommandText = insert;
157
158 if (ExecuteNonQuery(cmd) < 1)
159 return false;
160 }
161 }
162
163 return true;
164 }
165
166 public bool SetDataItem(UUID principalID, string item, string value)
167 {
168 using (MySqlCommand cmd
169 = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID"))
170 {
171 cmd.Parameters.AddWithValue("?"+item, value);
172 cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
173
174 if (ExecuteNonQuery(cmd) > 0)
175 return true;
176 }
177
178 return false;
179 }
180
181 public bool SetToken(UUID principalID, string token, int lifetime)
182 {
183 if (System.Environment.TickCount - m_LastExpire > 30000)
184 DoExpire();
185
186 using (MySqlCommand cmd
187 = new MySqlCommand(
188 "insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))"))
189 {
190 cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
191 cmd.Parameters.AddWithValue("?token", token);
192 cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
193
194 if (ExecuteNonQuery(cmd) > 0)
195 return true;
196 }
197
198 return false;
199 }
200
201 public bool CheckToken(UUID principalID, string token, int lifetime)
202 {
203 if (System.Environment.TickCount - m_LastExpire > 30000)
204 DoExpire();
205
206 using (MySqlCommand cmd
207 = new MySqlCommand(
208 "update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()"))
209 {
210 cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
211 cmd.Parameters.AddWithValue("?token", token);
212 cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
213
214 if (ExecuteNonQuery(cmd) > 0)
215 return true;
216 }
217
218 return false;
219 }
220
221 private void DoExpire()
222 {
223 using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()"))
224 {
225 ExecuteNonQuery(cmd);
226 }
227
228 m_LastExpire = System.Environment.TickCount;
229 }
230 }
231} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLAvatarData.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs
new file mode 100644
index 0000000..63e8020
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLAvatarData.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.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 MySQLAvatarData : MySQLGenericTableHandler<AvatarBaseData>,
44 IAvatarData
45 {
46// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public MySQLAvatarData(string connectionString, string realm) :
49 base(connectionString, realm, "Avatar")
50 {
51 }
52
53 public bool Delete(UUID principalID, string name)
54 {
55 using (MySqlCommand cmd = new MySqlCommand())
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 if (ExecuteNonQuery(cmd) > 0)
62 return true;
63 }
64
65 return false;
66 }
67 }
68}
diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs
new file mode 100644
index 0000000..eeedf02
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLEstateData.cs
@@ -0,0 +1,600 @@
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 MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Data;
38
39namespace OpenSim.Data.MySQL
40{
41 public class MySQLEstateStore : IEstateDataStore
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
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 protected virtual Assembly Assembly
53 {
54 get { return GetType().Assembly; }
55 }
56
57 public MySQLEstateStore()
58 {
59 }
60
61 public MySQLEstateStore(string connectionString)
62 {
63 Initialise(connectionString);
64 }
65
66 public void Initialise(string connectionString)
67 {
68 m_connectionString = connectionString;
69
70 try
71 {
72 m_log.Info("[REGION DB]: MySql - connecting: " + Util.GetDisplayConnectionString(m_connectionString));
73 }
74 catch (Exception e)
75 {
76 m_log.Debug("Exception: password not found in connection string\n" + e.ToString());
77 }
78
79 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
80 {
81 dbcon.Open();
82
83 Migration m = new Migration(dbcon, Assembly, "EstateStore");
84 m.Update();
85 dbcon.Close();
86
87 Type t = typeof(EstateSettings);
88 m_Fields = t.GetFields(BindingFlags.NonPublic |
89 BindingFlags.Instance |
90 BindingFlags.DeclaredOnly);
91
92 foreach (FieldInfo f in m_Fields)
93 {
94 if (f.Name.Substring(0, 2) == "m_")
95 m_FieldMap[f.Name.Substring(2)] = f;
96 }
97 }
98 }
99
100 private string[] FieldList
101 {
102 get { return new List<string>(m_FieldMap.Keys).ToArray(); }
103 }
104
105 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
106 {
107 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) +
108 " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID";
109
110 using (MySqlCommand cmd = new MySqlCommand())
111 {
112 cmd.CommandText = sql;
113 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
114
115 EstateSettings e = DoLoad(cmd, regionID, create);
116 if (!create && e.EstateID == 0) // Not found
117 return null;
118
119 return e;
120 }
121 }
122
123 public EstateSettings CreateNewEstate()
124 {
125 EstateSettings es = new EstateSettings();
126 es.OnSave += StoreEstateSettings;
127
128 DoCreate(es);
129
130 LoadBanList(es);
131
132 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
133 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
134 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
135
136 return es;
137 }
138
139 private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
140 {
141 EstateSettings es = new EstateSettings();
142 es.OnSave += StoreEstateSettings;
143
144 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
145 {
146 dbcon.Open();
147 cmd.Connection = dbcon;
148
149 bool found = false;
150
151 using (IDataReader r = cmd.ExecuteReader())
152 {
153 if (r.Read())
154 {
155 found = true;
156
157 foreach (string name in FieldList)
158 {
159 if (m_FieldMap[name].FieldType == typeof(bool))
160 {
161 m_FieldMap[name].SetValue(es, Convert.ToInt32(r[name]) != 0);
162 }
163 else if (m_FieldMap[name].FieldType == typeof(UUID))
164 {
165 m_FieldMap[name].SetValue(es, DBGuid.FromDB(r[name]));
166 }
167 else
168 {
169 m_FieldMap[name].SetValue(es, r[name]);
170 }
171 }
172 }
173 }
174 dbcon.Close();
175 cmd.Connection = null;
176
177 if (!found && create)
178 {
179 DoCreate(es);
180 LinkRegion(regionID, (int)es.EstateID);
181 }
182 }
183
184 LoadBanList(es);
185 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
186 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
187 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
188 return es;
189 }
190
191 private void DoCreate(EstateSettings es)
192 {
193 // Migration case
194 List<string> names = new List<string>(FieldList);
195
196 names.Remove("EstateID");
197
198 string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
199
200 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
201 {
202 dbcon.Open();
203 using (MySqlCommand cmd2 = dbcon.CreateCommand())
204 {
205 cmd2.CommandText = sql;
206 cmd2.Parameters.Clear();
207
208 foreach (string name in FieldList)
209 {
210 if (m_FieldMap[name].GetValue(es) is bool)
211 {
212 if ((bool)m_FieldMap[name].GetValue(es))
213 cmd2.Parameters.AddWithValue("?" + name, "1");
214 else
215 cmd2.Parameters.AddWithValue("?" + name, "0");
216 }
217 else
218 {
219 cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
220 }
221 }
222
223 cmd2.ExecuteNonQuery();
224
225 cmd2.CommandText = "select LAST_INSERT_ID() as id";
226 cmd2.Parameters.Clear();
227
228 using (IDataReader r = cmd2.ExecuteReader())
229 {
230 r.Read();
231 es.EstateID = Convert.ToUInt32(r["id"]);
232 }
233
234 es.Save();
235 }
236 dbcon.Close();
237 }
238 }
239
240 public void StoreEstateSettings(EstateSettings es)
241 {
242 string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
243
244 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
245 {
246 dbcon.Open();
247
248 using (MySqlCommand cmd = dbcon.CreateCommand())
249 {
250 cmd.CommandText = sql;
251
252 foreach (string name in FieldList)
253 {
254 if (m_FieldMap[name].GetValue(es) is bool)
255 {
256 if ((bool)m_FieldMap[name].GetValue(es))
257 cmd.Parameters.AddWithValue("?" + name, "1");
258 else
259 cmd.Parameters.AddWithValue("?" + name, "0");
260 }
261 else
262 {
263 cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
264 }
265 }
266
267 cmd.ExecuteNonQuery();
268 }
269 dbcon.Close();
270 }
271
272 SaveBanList(es);
273 SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
274 SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
275 SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
276 }
277
278 private void LoadBanList(EstateSettings es)
279 {
280 es.ClearBans();
281
282 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
283 {
284 dbcon.Open();
285
286 using (MySqlCommand cmd = dbcon.CreateCommand())
287 {
288 cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID";
289 cmd.Parameters.AddWithValue("?EstateID", es.EstateID);
290
291 using (IDataReader r = cmd.ExecuteReader())
292 {
293 while (r.Read())
294 {
295 EstateBan eb = new EstateBan();
296
297 UUID uuid = new UUID();
298 UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
299
300 eb.BannedUserID = uuid;
301 eb.BannedHostAddress = "0.0.0.0";
302 eb.BannedHostIPMask = "0.0.0.0";
303 es.AddBan(eb);
304 }
305 }
306 }
307 dbcon.Close();
308 }
309 }
310
311 private void SaveBanList(EstateSettings es)
312 {
313 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
314 {
315 dbcon.Open();
316
317 using (MySqlCommand cmd = dbcon.CreateCommand())
318 {
319 cmd.CommandText = "delete from estateban where EstateID = ?EstateID";
320 cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
321
322 cmd.ExecuteNonQuery();
323
324 cmd.Parameters.Clear();
325
326 cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )";
327
328 foreach (EstateBan b in es.EstateBans)
329 {
330 cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
331 cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString());
332
333 cmd.ExecuteNonQuery();
334 cmd.Parameters.Clear();
335 }
336 }
337 dbcon.Close();
338 }
339 }
340
341 void SaveUUIDList(uint EstateID, string table, UUID[] data)
342 {
343 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
344 {
345 dbcon.Open();
346
347 using (MySqlCommand cmd = dbcon.CreateCommand())
348 {
349 cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID";
350 cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString());
351
352 cmd.ExecuteNonQuery();
353
354 cmd.Parameters.Clear();
355
356 cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )";
357
358 foreach (UUID uuid in data)
359 {
360 cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString());
361 cmd.Parameters.AddWithValue("?uuid", uuid.ToString());
362
363 cmd.ExecuteNonQuery();
364 cmd.Parameters.Clear();
365 }
366 }
367 dbcon.Close();
368 }
369 }
370
371 UUID[] LoadUUIDList(uint EstateID, string table)
372 {
373 List<UUID> uuids = new List<UUID>();
374
375 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
376 {
377 dbcon.Open();
378
379 using (MySqlCommand cmd = dbcon.CreateCommand())
380 {
381 cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID";
382 cmd.Parameters.AddWithValue("?EstateID", EstateID);
383
384 using (IDataReader r = cmd.ExecuteReader())
385 {
386 while (r.Read())
387 {
388 // EstateBan eb = new EstateBan();
389 uuids.Add(DBGuid.FromDB(r["uuid"]));
390 }
391 }
392 }
393 dbcon.Close();
394 }
395
396 return uuids.ToArray();
397 }
398
399 public EstateSettings LoadEstateSettings(int estateID)
400 {
401 using (MySqlCommand cmd = new MySqlCommand())
402 {
403 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = ?EstateID";
404
405 cmd.CommandText = sql;
406 cmd.Parameters.AddWithValue("?EstateID", estateID);
407
408 EstateSettings e = DoLoad(cmd, UUID.Zero, false);
409 if (e.EstateID != estateID)
410 return null;
411 return e;
412 }
413 }
414
415 public List<EstateSettings> LoadEstateSettingsAll()
416 {
417 List<EstateSettings> allEstateSettings = new List<EstateSettings>();
418
419 List<int> allEstateIds = GetEstatesAll();
420
421 foreach (int estateId in allEstateIds)
422 allEstateSettings.Add(LoadEstateSettings(estateId));
423
424 return allEstateSettings;
425 }
426
427 public List<int> GetEstatesAll()
428 {
429 List<int> result = new List<int>();
430
431 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
432 {
433 dbcon.Open();
434
435 using (MySqlCommand cmd = dbcon.CreateCommand())
436 {
437 cmd.CommandText = "select estateID from estate_settings";
438
439 using (IDataReader reader = cmd.ExecuteReader())
440 {
441 while (reader.Read())
442 {
443 result.Add(Convert.ToInt32(reader["EstateID"]));
444 }
445 reader.Close();
446 }
447 }
448 dbcon.Close();
449 }
450
451 return result;
452 }
453
454 public List<int> GetEstates(string search)
455 {
456 List<int> result = new List<int>();
457
458 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
459 {
460 dbcon.Open();
461
462 using (MySqlCommand cmd = dbcon.CreateCommand())
463 {
464 cmd.CommandText = "select estateID from estate_settings where EstateName = ?EstateName";
465 cmd.Parameters.AddWithValue("?EstateName", search);
466
467 using (IDataReader reader = cmd.ExecuteReader())
468 {
469 while (reader.Read())
470 {
471 result.Add(Convert.ToInt32(reader["EstateID"]));
472 }
473 reader.Close();
474 }
475 }
476 dbcon.Close();
477 }
478
479 return result;
480 }
481
482 public List<int> GetEstatesByOwner(UUID ownerID)
483 {
484 List<int> result = new List<int>();
485
486 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
487 {
488 dbcon.Open();
489
490 using (MySqlCommand cmd = dbcon.CreateCommand())
491 {
492 cmd.CommandText = "select estateID from estate_settings where EstateOwner = ?EstateOwner";
493 cmd.Parameters.AddWithValue("?EstateOwner", ownerID);
494
495 using (IDataReader reader = cmd.ExecuteReader())
496 {
497 while (reader.Read())
498 {
499 result.Add(Convert.ToInt32(reader["EstateID"]));
500 }
501 reader.Close();
502 }
503 }
504
505 dbcon.Close();
506 }
507
508 return result;
509 }
510
511 public bool LinkRegion(UUID regionID, int estateID)
512 {
513 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
514 {
515 dbcon.Open();
516 MySqlTransaction transaction = dbcon.BeginTransaction();
517
518 try
519 {
520 // Delete any existing association of this region with an estate.
521 using (MySqlCommand cmd = dbcon.CreateCommand())
522 {
523 cmd.Transaction = transaction;
524 cmd.CommandText = "delete from estate_map where RegionID = ?RegionID";
525 cmd.Parameters.AddWithValue("?RegionID", regionID);
526
527 cmd.ExecuteNonQuery();
528 }
529
530 using (MySqlCommand cmd = dbcon.CreateCommand())
531 {
532 cmd.Transaction = transaction;
533 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
534 cmd.Parameters.AddWithValue("?RegionID", regionID);
535 cmd.Parameters.AddWithValue("?EstateID", estateID);
536
537 int ret = cmd.ExecuteNonQuery();
538
539 if (ret != 0)
540 transaction.Commit();
541 else
542 transaction.Rollback();
543
544 dbcon.Close();
545
546 return (ret != 0);
547 }
548 }
549 catch (MySqlException ex)
550 {
551 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
552 transaction.Rollback();
553 }
554
555 dbcon.Close();
556 }
557
558 return false;
559 }
560
561 public List<UUID> GetRegions(int estateID)
562 {
563 List<UUID> result = new List<UUID>();
564
565 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
566 {
567 dbcon.Open();
568
569 try
570 {
571 using (MySqlCommand cmd = dbcon.CreateCommand())
572 {
573 cmd.CommandText = "select RegionID from estate_map where EstateID = ?EstateID";
574 cmd.Parameters.AddWithValue("?EstateID", estateID.ToString());
575
576 using (IDataReader reader = cmd.ExecuteReader())
577 {
578 while(reader.Read())
579 result.Add(DBGuid.FromDB(reader["RegionID"]));
580 reader.Close();
581 }
582 }
583 }
584 catch (Exception e)
585 {
586 m_log.Error("[REGION DB]: Error reading estate map. " + e.ToString());
587 return result;
588 }
589 dbcon.Close();
590 }
591
592 return result;
593 }
594
595 public bool DeleteEstate(int estateID)
596 {
597 return false;
598 }
599 }
600}
diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs
new file mode 100644
index 0000000..6c48607
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs
@@ -0,0 +1,433 @@
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 System.Collections.Generic;
31using System.Data;
32using OpenSim.Framework;
33using OpenSim.Framework.Console;
34using log4net;
35using MySql.Data.MySqlClient;
36using OpenMetaverse;
37
38namespace OpenSim.Data.MySQL
39{
40 public class MySQLFSAssetData : IFSAssetDataPlugin
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 protected string m_ConnectionString;
45 protected string m_Table;
46
47 /// <summary>
48 /// Number of days that must pass before we update the access time on an asset when it has been fetched
49 /// Config option to change this is "DaysBetweenAccessTimeUpdates"
50 /// </summary>
51 private int DaysBetweenAccessTimeUpdates = 0;
52
53 protected virtual Assembly Assembly
54 {
55 get { return GetType().Assembly; }
56 }
57
58 public MySQLFSAssetData()
59 {
60 }
61
62 #region IPlugin Members
63
64 public string Version { get { return "1.0.0.0"; } }
65
66 // Loads and initialises the MySQL storage plugin and checks for migrations
67 public void Initialise(string connect, string realm, int UpdateAccessTime)
68 {
69 m_ConnectionString = connect;
70 m_Table = realm;
71
72 DaysBetweenAccessTimeUpdates = UpdateAccessTime;
73
74 try
75 {
76 using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
77 {
78 conn.Open();
79 Migration m = new Migration(conn, Assembly, "FSAssetStore");
80 m.Update();
81 conn.Close();
82 }
83 }
84 catch (MySqlException e)
85 {
86 m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", e.Message.ToString());
87 }
88 }
89
90 public void Initialise()
91 {
92 throw new NotImplementedException();
93 }
94
95 public void Dispose() { }
96
97 public string Name
98 {
99 get { return "MySQL FSAsset storage engine"; }
100 }
101
102 #endregion
103
104 private bool ExecuteNonQuery(MySqlCommand cmd)
105 {
106 using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
107 {
108 try
109 {
110 conn.Open();
111 }
112 catch (MySqlException e)
113 {
114 m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
115 return false;
116 }
117
118 cmd.Connection = conn;
119 try
120 {
121 cmd.ExecuteNonQuery();
122 }
123 catch (MySqlException e)
124 {
125 cmd.Connection = null;
126 conn.Close();
127 m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString());
128 return false;
129 }
130 conn.Close();
131 cmd.Connection = null;
132 }
133
134 return true;
135 }
136
137 #region IFSAssetDataPlugin Members
138
139 public AssetMetadata Get(string id, out string hash)
140 {
141 hash = String.Empty;
142
143 AssetMetadata meta = new AssetMetadata();
144
145 using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
146 {
147 try
148 {
149 conn.Open();
150 }
151 catch (MySqlException e)
152 {
153 m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
154 return null;
155 }
156
157 using (MySqlCommand cmd = conn.CreateCommand())
158 {
159 cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, asset_flags, access_time from {0} where id = ?id", m_Table);
160 cmd.Parameters.AddWithValue("?id", id);
161
162 using (IDataReader reader = cmd.ExecuteReader())
163 {
164 if (!reader.Read())
165 return null;
166
167 hash = reader["hash"].ToString();
168
169 meta.ID = id;
170 meta.FullID = new UUID(id);
171
172 meta.Name = reader["name"].ToString();
173 meta.Description = reader["description"].ToString();
174 meta.Type = (sbyte)Convert.ToInt32(reader["type"]);
175 meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
176 meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
177 meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]);
178
179 int AccessTime = Convert.ToInt32(reader["access_time"]);
180 UpdateAccessTime(id, AccessTime);
181 }
182 }
183 conn.Close();
184 }
185
186 return meta;
187 }
188
189 private void UpdateAccessTime(string AssetID, int AccessTime)
190 {
191 // Reduce DB work by only updating access time if asset hasn't recently been accessed
192 // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates"
193 if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
194 return;
195
196 using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
197 {
198 try
199 {
200 conn.Open();
201 }
202 catch (MySqlException e)
203 {
204 m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
205 return;
206 }
207
208 using (MySqlCommand cmd = conn.CreateCommand())
209 {
210 cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table);
211 cmd.Parameters.AddWithValue("?id", AssetID);
212 cmd.ExecuteNonQuery();
213 }
214 conn.Close();
215 }
216 }
217
218 public bool Store(AssetMetadata meta, string hash)
219 {
220 try
221 {
222 string oldhash;
223 AssetMetadata existingAsset = Get(meta.ID, out oldhash);
224
225 using (MySqlCommand cmd = new MySqlCommand())
226 {
227 cmd.Parameters.AddWithValue("?id", meta.ID);
228 cmd.Parameters.AddWithValue("?name", meta.Name);
229 cmd.Parameters.AddWithValue("?description", meta.Description);
230// cmd.Parameters.AddWithValue("?type", meta.Type.ToString());
231 cmd.Parameters.AddWithValue("?type", meta.Type);
232 cmd.Parameters.AddWithValue("?hash", hash);
233 cmd.Parameters.AddWithValue("?asset_flags", meta.Flags);
234
235 if (existingAsset == null)
236 {
237 cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table);
238
239 ExecuteNonQuery(cmd);
240
241 return true;
242 }
243
244 //cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table);
245
246 //ExecuteNonQuery(cmd);
247
248 }
249
250// return false;
251 // if the asset already exits
252 // assume it was already correctly stored
253 // or regions will keep retry.
254 return true;
255 }
256 catch(Exception e)
257 {
258 m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID);
259 m_log.Error(e.ToString());
260 return false;
261 }
262 }
263
264 /// <summary>
265 /// Check if the assets exist in the database.
266 /// </summary>
267 /// <param name="uuids">The asset UUID's</param>
268 /// <returns>For each asset: true if it exists, false otherwise</returns>
269 public bool[] AssetsExist(UUID[] uuids)
270 {
271 if (uuids.Length == 0)
272 return new bool[0];
273
274 bool[] results = new bool[uuids.Length];
275 for (int i = 0; i < uuids.Length; i++)
276 results[i] = false;
277
278 HashSet<UUID> exists = new HashSet<UUID>();
279
280 string ids = "'" + string.Join("','", uuids) + "'";
281 string sql = string.Format("select id from {1} where id in ({0})", ids, m_Table);
282
283 using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
284 {
285 try
286 {
287 conn.Open();
288 }
289 catch (MySqlException e)
290 {
291 m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString());
292 return results;
293 }
294
295 using (MySqlCommand cmd = conn.CreateCommand())
296 {
297 cmd.CommandText = sql;
298
299 using (MySqlDataReader dbReader = cmd.ExecuteReader())
300 {
301 while (dbReader.Read())
302 {
303 UUID id = DBGuid.FromDB(dbReader["ID"]);
304 exists.Add(id);
305 }
306 }
307 }
308 conn.Close();
309 }
310
311 for (int i = 0; i < uuids.Length; i++)
312 results[i] = exists.Contains(uuids[i]);
313 return results;
314 }
315
316 public int Count()
317 {
318 int count = 0;
319
320 using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
321 {
322 try
323 {
324 conn.Open();
325 }
326 catch (MySqlException e)
327 {
328 m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString());
329 return 0;
330 }
331
332 using(MySqlCommand cmd = conn.CreateCommand())
333 {
334 cmd.CommandText = String.Format("select count(*) as count from {0}",m_Table);
335
336 using (IDataReader reader = cmd.ExecuteReader())
337 {
338 reader.Read();
339
340 count = Convert.ToInt32(reader["count"]);
341 }
342 }
343 conn.Close();
344 }
345
346 return count;
347 }
348
349 public bool Delete(string id)
350 {
351 using(MySqlCommand cmd = new MySqlCommand())
352 {
353
354 cmd.CommandText = String.Format("delete from {0} where id = ?id",m_Table);
355
356 cmd.Parameters.AddWithValue("?id", id);
357
358 ExecuteNonQuery(cmd);
359 }
360
361 return true;
362 }
363
364 public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store)
365 {
366 int imported = 0;
367
368 using (MySqlConnection importConn = new MySqlConnection(conn))
369 {
370 try
371 {
372 importConn.Open();
373 }
374 catch (MySqlException e)
375 {
376 m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}",
377 e.Message.ToString());
378
379 return;
380 }
381
382 using (MySqlCommand cmd = importConn.CreateCommand())
383 {
384 string limit = String.Empty;
385 if (count != -1)
386 {
387 limit = String.Format(" limit {0},{1}", start, count);
388 }
389
390 cmd.CommandText = String.Format("select * from {0}{1}", table, limit);
391
392 MainConsole.Instance.Output("Querying database");
393 using (IDataReader reader = cmd.ExecuteReader())
394 {
395 MainConsole.Instance.Output("Reading data");
396
397 while (reader.Read())
398 {
399 if ((imported % 100) == 0)
400 {
401 MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported));
402 }
403
404 AssetBase asset = new AssetBase();
405 AssetMetadata meta = new AssetMetadata();
406
407 meta.ID = reader["id"].ToString();
408 meta.FullID = new UUID(meta.ID);
409
410 meta.Name = reader["name"].ToString();
411 meta.Description = reader["description"].ToString();
412 meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]);
413 meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
414 meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
415
416 asset.Metadata = meta;
417 asset.Data = (byte[])reader["data"];
418
419 store(asset, force);
420
421 imported++;
422 }
423 }
424 }
425 importConn.Close();
426 }
427
428 MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));
429 }
430
431 #endregion
432 }
433}
diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs
new file mode 100644
index 0000000..98106f0
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLFramework.cs
@@ -0,0 +1,121 @@
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 /// <summary>
39 /// Common code for a number of database modules
40 /// </summary>
41 public class MySqlFramework
42 {
43 private static readonly log4net.ILog m_log =
44 log4net.LogManager.GetLogger(
45 System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
46
47 protected string m_connectionString = String.Empty;
48 protected MySqlTransaction m_trans = null;
49
50 // Constructor using a connection string. Instances constructed
51 // this way will open a new connection for each call.
52 protected MySqlFramework(string connectionString)
53 {
54 m_connectionString = connectionString;
55 }
56
57 // Constructor using a connection object. Instances constructed
58 // this way will use the connection object and never create
59 // new connections.
60 protected MySqlFramework(MySqlTransaction trans)
61 {
62 m_trans = trans;
63 }
64
65 //////////////////////////////////////////////////////////////
66 //
67 // All non queries are funneled through one connection
68 // to increase performance a little
69 //
70 protected int ExecuteNonQuery(MySqlCommand cmd)
71 {
72 if (m_trans == null)
73 {
74 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
75 {
76 dbcon.Open();
77 int ret = ExecuteNonQueryWithConnection(cmd, dbcon);
78 dbcon.Close();
79 return ret;
80 }
81 }
82 else
83 {
84 return ExecuteNonQueryWithTransaction(cmd, m_trans);
85 }
86 }
87
88 private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
89 {
90 cmd.Transaction = trans;
91 return ExecuteNonQueryWithConnection(cmd, trans.Connection);
92 }
93
94 private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
95 {
96 try
97 {
98 cmd.Connection = dbcon;
99
100 try
101 {
102 int ret = cmd.ExecuteNonQuery();
103 cmd.Connection = null;
104 return ret;
105 }
106 catch (Exception e)
107 {
108 m_log.Error(e.Message, e);
109 m_log.Error(Environment.StackTrace.ToString());
110 cmd.Connection = null;
111 return 0;
112 }
113 }
114 catch (Exception e)
115 {
116 m_log.Error(e.Message, e);
117 return 0;
118 }
119 }
120 }
121}
diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs
new file mode 100644
index 0000000..6ba9fbd
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs
@@ -0,0 +1,86 @@
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 return Delete(principalID.ToString(), friend);
48 }
49
50 public override bool Delete(string principalID, string friend)
51 {
52 using (MySqlCommand cmd = new MySqlCommand())
53 {
54 cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
55 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
56 cmd.Parameters.AddWithValue("?Friend", friend);
57
58 ExecuteNonQuery(cmd);
59 }
60
61 return true;
62 }
63
64 public FriendsData[] GetFriends(UUID principalID)
65 {
66 using (MySqlCommand cmd = new MySqlCommand())
67 {
68 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);
69 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
70
71 return DoQuery(cmd);
72 }
73 }
74
75 public FriendsData[] GetFriends(string principalID)
76 {
77 using (MySqlCommand cmd = new MySqlCommand())
78 {
79 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 LIKE ?PrincipalID", m_Realm);
80 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
81
82 return DoQuery(cmd);
83 }
84 }
85 }
86} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
new file mode 100644
index 0000000..9bd3c0c
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
@@ -0,0 +1,421 @@
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 MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37
38namespace OpenSim.Data.MySQL
39{
40 public class MySQLGenericTableHandler<T> : MySqlFramework 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 virtual Assembly Assembly
52 {
53 get { return GetType().Assembly; }
54 }
55
56 public MySQLGenericTableHandler(MySqlTransaction trans,
57 string realm, string storeName) : base(trans)
58 {
59 m_Realm = realm;
60
61 CommonConstruct(storeName);
62 }
63
64 public MySQLGenericTableHandler(string connectionString,
65 string realm, string storeName) : base(connectionString)
66 {
67 m_Realm = realm;
68
69 CommonConstruct(storeName);
70 }
71
72 protected void CommonConstruct(string storeName)
73 {
74 if (storeName != String.Empty)
75 {
76 // We always use a new connection for any Migrations
77 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
78 {
79 dbcon.Open();
80 Migration m = new Migration(dbcon, Assembly, storeName);
81 m.Update();
82 }
83 }
84
85 Type t = typeof(T);
86 FieldInfo[] fields = t.GetFields(BindingFlags.Public |
87 BindingFlags.Instance |
88 BindingFlags.DeclaredOnly);
89
90 if (fields.Length == 0)
91 return;
92
93 foreach (FieldInfo f in fields)
94 {
95 if (f.Name != "Data")
96 m_Fields[f.Name] = f;
97 else
98 m_DataField = f;
99 }
100 }
101
102 private void CheckColumnNames(IDataReader reader)
103 {
104 if (m_ColumnNames != null)
105 return;
106
107 List<string> columnNames = new List<string>();
108
109 DataTable schemaTable = reader.GetSchemaTable();
110 foreach (DataRow row in schemaTable.Rows)
111 {
112 if (row["ColumnName"] != null &&
113 (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
114 columnNames.Add(row["ColumnName"].ToString());
115 }
116
117 m_ColumnNames = columnNames;
118 }
119
120 public virtual T[] Get(string field, string key)
121 {
122 return Get(new string[] { field }, new string[] { key });
123 }
124
125 public virtual T[] Get(string[] fields, string[] keys)
126 {
127 return Get(fields, keys, String.Empty);
128 }
129
130 public virtual T[] Get(string[] fields, string[] keys, string options)
131 {
132 if (fields.Length != keys.Length)
133 return new T[0];
134
135 List<string> terms = new List<string>();
136
137 using (MySqlCommand cmd = new MySqlCommand())
138 {
139 for (int i = 0 ; i < fields.Length ; i++)
140 {
141 cmd.Parameters.AddWithValue(fields[i], keys[i]);
142 terms.Add("`" + fields[i] + "` = ?" + fields[i]);
143 }
144
145 string where = String.Join(" and ", terms.ToArray());
146
147 string query = String.Format("select * from {0} where {1} {2}",
148 m_Realm, where, options);
149
150 cmd.CommandText = query;
151
152 return DoQuery(cmd);
153 }
154 }
155
156 protected T[] DoQuery(MySqlCommand cmd)
157 {
158 if (m_trans == null)
159 {
160 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
161 {
162 dbcon.Open();
163 T[] ret = DoQueryWithConnection(cmd, dbcon);
164 dbcon.Close();
165 return ret;
166 }
167 }
168 else
169 {
170 return DoQueryWithTransaction(cmd, m_trans);
171 }
172 }
173
174 protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
175 {
176 cmd.Transaction = trans;
177
178 return DoQueryWithConnection(cmd, trans.Connection);
179 }
180
181 protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
182 {
183 List<T> result = new List<T>();
184
185 cmd.Connection = dbcon;
186
187 using (IDataReader reader = cmd.ExecuteReader())
188 {
189 if (reader == null)
190 return new T[0];
191
192 CheckColumnNames(reader);
193
194 while (reader.Read())
195 {
196 T row = new T();
197
198 foreach (string name in m_Fields.Keys)
199 {
200 if (reader[name] is DBNull)
201 {
202 continue;
203 }
204 if (m_Fields[name].FieldType == typeof(bool))
205 {
206 int v = Convert.ToInt32(reader[name]);
207 m_Fields[name].SetValue(row, v != 0 ? true : false);
208 }
209 else if (m_Fields[name].FieldType == typeof(UUID))
210 {
211 m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
212 }
213 else if (m_Fields[name].FieldType == typeof(int))
214 {
215 int v = Convert.ToInt32(reader[name]);
216 m_Fields[name].SetValue(row, v);
217 }
218 else if (m_Fields[name].FieldType == typeof(uint))
219 {
220 uint v = Convert.ToUInt32(reader[name]);
221 m_Fields[name].SetValue(row, v);
222 }
223 else
224 {
225 m_Fields[name].SetValue(row, reader[name]);
226 }
227 }
228
229 if (m_DataField != null)
230 {
231 Dictionary<string, string> data =
232 new Dictionary<string, string>();
233
234 foreach (string col in m_ColumnNames)
235 {
236 data[col] = reader[col].ToString();
237 if (data[col] == null)
238 data[col] = String.Empty;
239 }
240
241 m_DataField.SetValue(row, data);
242 }
243
244 result.Add(row);
245 }
246 }
247 cmd.Connection = null;
248 return result.ToArray();
249 }
250
251 public virtual T[] Get(string where)
252 {
253 using (MySqlCommand cmd = new MySqlCommand())
254 {
255 string query = String.Format("select * from {0} where {1}",
256 m_Realm, where);
257
258 cmd.CommandText = query;
259
260 return DoQuery(cmd);
261 }
262 }
263
264 public virtual bool Store(T row)
265 {
266// m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked");
267
268 using (MySqlCommand cmd = new MySqlCommand())
269 {
270 string query = "";
271 List<String> names = new List<String>();
272 List<String> values = new List<String>();
273
274 foreach (FieldInfo fi in m_Fields.Values)
275 {
276 names.Add(fi.Name);
277 values.Add("?" + fi.Name);
278
279 // Temporarily return more information about what field is unexpectedly null for
280 // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
281 // InventoryTransferModule or we may be required to substitute a DBNull here.
282 if (fi.GetValue(row) == null)
283 throw new NullReferenceException(
284 string.Format(
285 "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
286 fi.Name, row));
287
288 cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString());
289 }
290
291 if (m_DataField != null)
292 {
293 Dictionary<string, string> data =
294 (Dictionary<string, string>)m_DataField.GetValue(row);
295
296 foreach (KeyValuePair<string, string> kvp in data)
297 {
298 names.Add(kvp.Key);
299 values.Add("?" + kvp.Key);
300 cmd.Parameters.AddWithValue("?" + kvp.Key, kvp.Value);
301 }
302 }
303
304 query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
305
306 cmd.CommandText = query;
307
308 if (ExecuteNonQuery(cmd) > 0)
309 return true;
310
311 return false;
312 }
313 }
314
315 public virtual bool Delete(string field, string key)
316 {
317 return Delete(new string[] { field }, new string[] { key });
318 }
319
320 public virtual bool Delete(string[] fields, string[] keys)
321 {
322// m_log.DebugFormat(
323// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
324// string.Join(",", fields), string.Join(",", keys));
325
326 if (fields.Length != keys.Length)
327 return false;
328
329 List<string> terms = new List<string>();
330
331 using (MySqlCommand cmd = new MySqlCommand())
332 {
333 for (int i = 0 ; i < fields.Length ; i++)
334 {
335 cmd.Parameters.AddWithValue(fields[i], keys[i]);
336 terms.Add("`" + fields[i] + "` = ?" + fields[i]);
337 }
338
339 string where = String.Join(" and ", terms.ToArray());
340
341 string query = String.Format("delete from {0} where {1}", m_Realm, where);
342
343 cmd.CommandText = query;
344
345 return ExecuteNonQuery(cmd) > 0;
346 }
347 }
348
349 public long GetCount(string field, string key)
350 {
351 return GetCount(new string[] { field }, new string[] { key });
352 }
353
354 public long GetCount(string[] fields, string[] keys)
355 {
356 if (fields.Length != keys.Length)
357 return 0;
358
359 List<string> terms = new List<string>();
360
361 using (MySqlCommand cmd = new MySqlCommand())
362 {
363 for (int i = 0; i < fields.Length; i++)
364 {
365 cmd.Parameters.AddWithValue(fields[i], keys[i]);
366 terms.Add("`" + fields[i] + "` = ?" + fields[i]);
367 }
368
369 string where = String.Join(" and ", terms.ToArray());
370
371 string query = String.Format("select count(*) from {0} where {1}",
372 m_Realm, where);
373
374 cmd.CommandText = query;
375
376 Object result = DoQueryScalar(cmd);
377
378 return Convert.ToInt64(result);
379 }
380 }
381
382 public long GetCount(string where)
383 {
384 using (MySqlCommand cmd = new MySqlCommand())
385 {
386 string query = String.Format("select count(*) from {0} where {1}",
387 m_Realm, where);
388
389 cmd.CommandText = query;
390
391 object result = DoQueryScalar(cmd);
392
393 return Convert.ToInt64(result);
394 }
395 }
396
397 public object DoQueryScalar(MySqlCommand cmd)
398 {
399 if (m_trans == null)
400 {
401 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
402 {
403 dbcon.Open();
404 cmd.Connection = dbcon;
405
406 Object ret = cmd.ExecuteScalar();
407 cmd.Connection = null;
408 dbcon.Close();
409 return ret;
410 }
411 }
412 else
413 {
414 cmd.Connection = m_trans.Connection;
415 cmd.Transaction = m_trans;
416
417 return cmd.ExecuteScalar();
418 }
419 }
420 }
421}
diff --git a/OpenSim/Data/MySQL/MySQLGridUserData.cs b/OpenSim/Data/MySQL/MySQLGridUserData.cs
new file mode 100644
index 0000000..00560c1
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLGridUserData.cs
@@ -0,0 +1,64 @@
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 user grid data
42 /// </summary>
43 public class MySQLGridUserData : MySQLGenericTableHandler<GridUserData>, IGridUserData
44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "GridUserStore") {}
48
49 public new GridUserData Get(string userID)
50 {
51 GridUserData[] ret = Get("UserID", userID);
52
53 if (ret.Length == 0)
54 return null;
55
56 return ret[0];
57 }
58
59 public GridUserData[] GetAll(string userID)
60 {
61 return base.Get(String.Format("UserID LIKE '{0}%'", userID));
62 }
63 }
64} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLGroupsData.cs b/OpenSim/Data/MySQL/MySQLGroupsData.cs
new file mode 100644
index 0000000..4e73ee7
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLGroupsData.cs
@@ -0,0 +1,483 @@
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;
32
33using OpenSim.Framework;
34using OpenSim.Data.MySQL;
35
36using OpenMetaverse;
37using MySql.Data.MySqlClient;
38
39namespace OpenSim.Data.MySQL
40{
41 public class MySQLGroupsData : IGroupsData
42 {
43 private MySqlGroupsGroupsHandler m_Groups;
44 private MySqlGroupsMembershipHandler m_Membership;
45 private MySqlGroupsRolesHandler m_Roles;
46 private MySqlGroupsRoleMembershipHandler m_RoleMembership;
47 private MySqlGroupsInvitesHandler m_Invites;
48 private MySqlGroupsNoticesHandler m_Notices;
49 private MySqlGroupsPrincipalsHandler m_Principals;
50
51 public MySQLGroupsData(string connectionString, string realm)
52 {
53 m_Groups = new MySqlGroupsGroupsHandler(connectionString, realm + "_groups", realm + "_Store");
54 m_Membership = new MySqlGroupsMembershipHandler(connectionString, realm + "_membership");
55 m_Roles = new MySqlGroupsRolesHandler(connectionString, realm + "_roles");
56 m_RoleMembership = new MySqlGroupsRoleMembershipHandler(connectionString, realm + "_rolemembership");
57 m_Invites = new MySqlGroupsInvitesHandler(connectionString, realm + "_invites");
58 m_Notices = new MySqlGroupsNoticesHandler(connectionString, realm + "_notices");
59 m_Principals = new MySqlGroupsPrincipalsHandler(connectionString, realm + "_principals");
60 }
61
62 #region groups table
63 public bool StoreGroup(GroupData data)
64 {
65 return m_Groups.Store(data);
66 }
67
68 public GroupData RetrieveGroup(UUID groupID)
69 {
70 GroupData[] groups = m_Groups.Get("GroupID", groupID.ToString());
71 if (groups.Length > 0)
72 return groups[0];
73
74 return null;
75 }
76
77 public GroupData RetrieveGroup(string name)
78 {
79 GroupData[] groups = m_Groups.Get("Name", name);
80 if (groups.Length > 0)
81 return groups[0];
82
83 return null;
84 }
85
86 public GroupData[] RetrieveGroups(string pattern)
87 {
88 if (string.IsNullOrEmpty(pattern))
89 pattern = "1";
90 else
91 pattern = string.Format("Name LIKE '%{0}%'", MySqlHelper.EscapeString(pattern));
92
93 return m_Groups.Get(string.Format("ShowInList=1 AND ({0}) ORDER BY Name LIMIT 100", pattern));
94 }
95
96 public bool DeleteGroup(UUID groupID)
97 {
98 return m_Groups.Delete("GroupID", groupID.ToString());
99 }
100
101 public int GroupsCount()
102 {
103 return (int)m_Groups.GetCount("Location=\"\"");
104 }
105
106 #endregion
107
108 #region membership table
109 public MembershipData[] RetrieveMembers(UUID groupID)
110 {
111 return m_Membership.Get("GroupID", groupID.ToString());
112 }
113
114 public MembershipData RetrieveMember(UUID groupID, string pricipalID)
115 {
116 MembershipData[] m = m_Membership.Get(new string[] { "GroupID", "PrincipalID" },
117 new string[] { groupID.ToString(), pricipalID });
118 if (m != null && m.Length > 0)
119 return m[0];
120
121 return null;
122 }
123
124 public MembershipData[] RetrieveMemberships(string pricipalID)
125 {
126 return m_Membership.Get("PrincipalID", pricipalID.ToString());
127 }
128
129 public bool StoreMember(MembershipData data)
130 {
131 return m_Membership.Store(data);
132 }
133
134 public bool DeleteMember(UUID groupID, string pricipalID)
135 {
136 return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" },
137 new string[] { groupID.ToString(), pricipalID });
138 }
139
140 public int MemberCount(UUID groupID)
141 {
142 return (int)m_Membership.GetCount("GroupID", groupID.ToString());
143 }
144 #endregion
145
146 #region roles table
147 public bool StoreRole(RoleData data)
148 {
149 return m_Roles.Store(data);
150 }
151
152 public RoleData RetrieveRole(UUID groupID, UUID roleID)
153 {
154 RoleData[] data = m_Roles.Get(new string[] { "GroupID", "RoleID" },
155 new string[] { groupID.ToString(), roleID.ToString() });
156
157 if (data != null && data.Length > 0)
158 return data[0];
159
160 return null;
161 }
162
163 public RoleData[] RetrieveRoles(UUID groupID)
164 {
165 //return m_Roles.RetrieveRoles(groupID);
166 return m_Roles.Get("GroupID", groupID.ToString());
167 }
168
169 public bool DeleteRole(UUID groupID, UUID roleID)
170 {
171 return m_Roles.Delete(new string[] { "GroupID", "RoleID" },
172 new string[] { groupID.ToString(), roleID.ToString() });
173 }
174
175 public int RoleCount(UUID groupID)
176 {
177 return (int)m_Roles.GetCount("GroupID", groupID.ToString());
178 }
179
180
181 #endregion
182
183 #region rolememberhip table
184 public RoleMembershipData[] RetrieveRolesMembers(UUID groupID)
185 {
186 RoleMembershipData[] data = m_RoleMembership.Get("GroupID", groupID.ToString());
187
188 return data;
189 }
190
191 public RoleMembershipData[] RetrieveRoleMembers(UUID groupID, UUID roleID)
192 {
193 RoleMembershipData[] data = m_RoleMembership.Get(new string[] { "GroupID", "RoleID" },
194 new string[] { groupID.ToString(), roleID.ToString() });
195
196 return data;
197 }
198
199 public RoleMembershipData[] RetrieveMemberRoles(UUID groupID, string principalID)
200 {
201 RoleMembershipData[] data = m_RoleMembership.Get(new string[] { "GroupID", "PrincipalID" },
202 new string[] { groupID.ToString(), principalID.ToString() });
203
204 return data;
205 }
206
207 public RoleMembershipData RetrieveRoleMember(UUID groupID, UUID roleID, string principalID)
208 {
209 RoleMembershipData[] data = m_RoleMembership.Get(new string[] { "GroupID", "RoleID", "PrincipalID" },
210 new string[] { groupID.ToString(), roleID.ToString(), principalID.ToString() });
211
212 if (data != null && data.Length > 0)
213 return data[0];
214
215 return null;
216 }
217
218 public int RoleMemberCount(UUID groupID, UUID roleID)
219 {
220 return (int)m_RoleMembership.GetCount(new string[] { "GroupID", "RoleID" },
221 new string[] { groupID.ToString(), roleID.ToString() });
222 }
223
224 public bool StoreRoleMember(RoleMembershipData data)
225 {
226 return m_RoleMembership.Store(data);
227 }
228
229 public bool DeleteRoleMember(RoleMembershipData data)
230 {
231 return m_RoleMembership.Delete(new string[] { "GroupID", "RoleID", "PrincipalID"},
232 new string[] { data.GroupID.ToString(), data.RoleID.ToString(), data.PrincipalID });
233 }
234
235 public bool DeleteMemberAllRoles(UUID groupID, string principalID)
236 {
237 return m_RoleMembership.Delete(new string[] { "GroupID", "PrincipalID" },
238 new string[] { groupID.ToString(), principalID });
239 }
240
241 #endregion
242
243 #region principals table
244 public bool StorePrincipal(PrincipalData data)
245 {
246 return m_Principals.Store(data);
247 }
248
249 public PrincipalData RetrievePrincipal(string principalID)
250 {
251 PrincipalData[] p = m_Principals.Get("PrincipalID", principalID);
252 if (p != null && p.Length > 0)
253 return p[0];
254
255 return null;
256 }
257
258 public bool DeletePrincipal(string principalID)
259 {
260 return m_Principals.Delete("PrincipalID", principalID);
261 }
262 #endregion
263
264 #region invites table
265
266 public bool StoreInvitation(InvitationData data)
267 {
268 return m_Invites.Store(data);
269 }
270
271 public InvitationData RetrieveInvitation(UUID inviteID)
272 {
273 InvitationData[] invites = m_Invites.Get("InviteID", inviteID.ToString());
274
275 if (invites != null && invites.Length > 0)
276 return invites[0];
277
278 return null;
279 }
280
281 public InvitationData RetrieveInvitation(UUID groupID, string principalID)
282 {
283 InvitationData[] invites = m_Invites.Get(new string[] { "GroupID", "PrincipalID" },
284 new string[] { groupID.ToString(), principalID });
285
286 if (invites != null && invites.Length > 0)
287 return invites[0];
288
289 return null;
290 }
291
292 public bool DeleteInvite(UUID inviteID)
293 {
294 return m_Invites.Delete("InviteID", inviteID.ToString());
295 }
296
297 public void DeleteOldInvites()
298 {
299 m_Invites.DeleteOld();
300 }
301
302 #endregion
303
304 #region notices table
305
306 public bool StoreNotice(NoticeData data)
307 {
308 return m_Notices.Store(data);
309 }
310
311 public NoticeData RetrieveNotice(UUID noticeID)
312 {
313 NoticeData[] notices = m_Notices.Get("NoticeID", noticeID.ToString());
314
315 if (notices != null && notices.Length > 0)
316 return notices[0];
317
318 return null;
319 }
320
321 public NoticeData[] RetrieveNotices(UUID groupID)
322 {
323 NoticeData[] notices = m_Notices.Get("GroupID", groupID.ToString());
324
325 return notices;
326 }
327
328 public bool DeleteNotice(UUID noticeID)
329 {
330 return m_Notices.Delete("NoticeID", noticeID.ToString());
331 }
332
333 public void DeleteOldNotices()
334 {
335 m_Notices.DeleteOld();
336 }
337
338 #endregion
339
340 #region combinations
341 public MembershipData RetrievePrincipalGroupMembership(string principalID, UUID groupID)
342 {
343 // TODO
344 return null;
345 }
346 public MembershipData[] RetrievePrincipalGroupMemberships(string principalID)
347 {
348 // TODO
349 return null;
350 }
351
352 #endregion
353 }
354
355 public class MySqlGroupsGroupsHandler : MySQLGenericTableHandler<GroupData>
356 {
357 protected override Assembly Assembly
358 {
359 // WARNING! Moving migrations to this assembly!!!
360 get { return GetType().Assembly; }
361 }
362
363 public MySqlGroupsGroupsHandler(string connectionString, string realm, string store)
364 : base(connectionString, realm, store)
365 {
366 }
367
368 }
369
370 public class MySqlGroupsMembershipHandler : MySQLGenericTableHandler<MembershipData>
371 {
372 protected override Assembly Assembly
373 {
374 // WARNING! Moving migrations to this assembly!!!
375 get { return GetType().Assembly; }
376 }
377
378 public MySqlGroupsMembershipHandler(string connectionString, string realm)
379 : base(connectionString, realm, string.Empty)
380 {
381 }
382
383 }
384
385 public class MySqlGroupsRolesHandler : MySQLGenericTableHandler<RoleData>
386 {
387 protected override Assembly Assembly
388 {
389 // WARNING! Moving migrations to this assembly!!!
390 get { return GetType().Assembly; }
391 }
392
393 public MySqlGroupsRolesHandler(string connectionString, string realm)
394 : base(connectionString, realm, string.Empty)
395 {
396 }
397
398 }
399
400 public class MySqlGroupsRoleMembershipHandler : MySQLGenericTableHandler<RoleMembershipData>
401 {
402 protected override Assembly Assembly
403 {
404 // WARNING! Moving migrations to this assembly!!!
405 get { return GetType().Assembly; }
406 }
407
408 public MySqlGroupsRoleMembershipHandler(string connectionString, string realm)
409 : base(connectionString, realm, string.Empty)
410 {
411 }
412
413 }
414
415 public class MySqlGroupsInvitesHandler : MySQLGenericTableHandler<InvitationData>
416 {
417 protected override Assembly Assembly
418 {
419 // WARNING! Moving migrations to this assembly!!!
420 get { return GetType().Assembly; }
421 }
422
423 public MySqlGroupsInvitesHandler(string connectionString, string realm)
424 : base(connectionString, realm, string.Empty)
425 {
426 }
427
428 public void DeleteOld()
429 {
430 uint now = (uint)Util.UnixTimeSinceEpoch();
431
432 using (MySqlCommand cmd = new MySqlCommand())
433 {
434 cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
435
436 ExecuteNonQuery(cmd);
437 }
438
439 }
440 }
441
442 public class MySqlGroupsNoticesHandler : MySQLGenericTableHandler<NoticeData>
443 {
444 protected override Assembly Assembly
445 {
446 // WARNING! Moving migrations to this assembly!!!
447 get { return GetType().Assembly; }
448 }
449
450 public MySqlGroupsNoticesHandler(string connectionString, string realm)
451 : base(connectionString, realm, string.Empty)
452 {
453 }
454
455 public void DeleteOld()
456 {
457 uint now = (uint)Util.UnixTimeSinceEpoch();
458
459 using (MySqlCommand cmd = new MySqlCommand())
460 {
461 cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm);
462 cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old
463
464 ExecuteNonQuery(cmd);
465 }
466
467 }
468 }
469
470 public class MySqlGroupsPrincipalsHandler : MySQLGenericTableHandler<PrincipalData>
471 {
472 protected override Assembly Assembly
473 {
474 // WARNING! Moving migrations to this assembly!!!
475 get { return GetType().Assembly; }
476 }
477
478 public MySqlGroupsPrincipalsHandler(string connectionString, string realm)
479 : base(connectionString, realm, string.Empty)
480 {
481 }
482 }
483}
diff --git a/OpenSim/Data/MySQL/MySQLHGTravelData.cs b/OpenSim/Data/MySQL/MySQLHGTravelData.cs
new file mode 100644
index 0000000..e81b880
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLHGTravelData.cs
@@ -0,0 +1,80 @@
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 user grid data
42 /// </summary>
43 public class MySQLHGTravelData : MySQLGenericTableHandler<HGTravelingData>, IHGTravelingData
44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 public MySQLHGTravelData(string connectionString, string realm) : base(connectionString, realm, "HGTravelStore") { }
48
49 public HGTravelingData Get(UUID sessionID)
50 {
51 HGTravelingData[] ret = Get("SessionID", sessionID.ToString());
52
53 if (ret.Length == 0)
54 return null;
55
56 return ret[0];
57 }
58
59 public HGTravelingData[] GetSessions(UUID userID)
60 {
61 return base.Get("UserID", userID.ToString());
62 }
63
64 public bool Delete(UUID sessionID)
65 {
66 return Delete("SessionID", sessionID.ToString());
67 }
68
69 public void DeleteOld()
70 {
71 using (MySqlCommand cmd = new MySqlCommand())
72 {
73 cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 DAY", m_Realm);
74
75 ExecuteNonQuery(cmd);
76 }
77
78 }
79 }
80} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs
new file mode 100644
index 0000000..cc787cc
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs
@@ -0,0 +1,916 @@
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.Reflection;
31using log4net;
32using MySql.Data.MySqlClient;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Data;
36
37namespace OpenSim.Data.MySQL
38{
39 /// <summary>
40 /// A MySQL interface for the inventory server
41 /// </summary>
42 public class MySQLInventoryData : IInventoryDataPlugin
43 {
44 private static readonly ILog m_log
45 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 private string m_connectionString;
48 private object m_dbLock = new object();
49
50 public string Version { get { return "1.0.0.0"; } }
51
52 public void Initialise()
53 {
54 m_log.Info("[MySQLInventoryData]: " + Name + " cannot be default-initialized!");
55 throw new PluginNotInitialisedException (Name);
56 }
57
58 /// <summary>
59 /// <para>Initialises Inventory interface</para>
60 /// <para>
61 /// <list type="bullet">
62 /// <item>Loads and initialises the MySQL storage plugin</item>
63 /// <item>warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
64 /// <item>Check for migration</item>
65 /// </list>
66 /// </para>
67 /// </summary>
68 /// <param name="connect">connect string</param>
69 public void Initialise(string connect)
70 {
71 m_connectionString = 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 dbcon.Open();
79 Migration m = new Migration(dbcon, assem, "InventoryStore");
80 m.Update();
81 dbcon.Close();
82 }
83 }
84
85 /// <summary>
86 /// The name of this DB provider
87 /// </summary>
88 /// <returns>Name of DB provider</returns>
89 public string Name
90 {
91 get { return "MySQL Inventory Data Interface"; }
92 }
93
94 /// <summary>
95 /// Closes this DB provider
96 /// </summary>
97 /// <remarks>do nothing</remarks>
98 public void Dispose()
99 {
100 // Do nothing.
101 }
102
103 /// <summary>
104 /// Returns a list of items in a specified folder
105 /// </summary>
106 /// <param name="folderID">The folder to search</param>
107 /// <returns>A list containing inventory items</returns>
108 public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
109 {
110 try
111 {
112 lock (m_dbLock)
113 {
114 List<InventoryItemBase> items = new List<InventoryItemBase>();
115
116 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
117 {
118 dbcon.Open();
119
120 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", dbcon))
121 {
122 result.Parameters.AddWithValue("?uuid", folderID.ToString());
123
124 using (MySqlDataReader reader = result.ExecuteReader())
125 {
126 while (reader.Read())
127 {
128 // A null item (because something went wrong) breaks everything in the folder
129 InventoryItemBase item = readInventoryItem(reader);
130 if (item != null)
131 items.Add(item);
132 }
133
134 dbcon.Close();
135 return items;
136 }
137 }
138 }
139 }
140 }
141 catch (Exception e)
142 {
143 m_log.Error(e.Message, e);
144 return null;
145 }
146 }
147
148 /// <summary>
149 /// Returns a list of the root folders within a users inventory
150 /// </summary>
151 /// <param name="user">The user whose inventory is to be searched</param>
152 /// <returns>A list of folder objects</returns>
153 public List<InventoryFolderBase> getUserRootFolders(UUID user)
154 {
155 try
156 {
157 lock (m_dbLock)
158 {
159 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
160 {
161 dbcon.Open();
162
163 using (MySqlCommand result = new MySqlCommand(
164 "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon))
165 {
166 result.Parameters.AddWithValue("?uuid", user.ToString());
167 result.Parameters.AddWithValue("?zero", UUID.Zero.ToString());
168
169 using (MySqlDataReader reader = result.ExecuteReader())
170 {
171 List<InventoryFolderBase> items = new List<InventoryFolderBase>();
172 while (reader.Read())
173 items.Add(readInventoryFolder(reader));
174
175 dbcon.Close();
176 return items;
177 }
178 }
179 }
180 }
181 }
182 catch (Exception e)
183 {
184 m_log.Error(e.Message, e);
185 return null;
186 }
187 }
188
189
190 /// <summary>
191 /// see <see cref="InventoryItemBase.getUserRootFolder"/>
192 /// </summary>
193 /// <param name="user">The user UUID</param>
194 /// <returns></returns>
195 public InventoryFolderBase getUserRootFolder(UUID user)
196 {
197 try
198 {
199 lock (m_dbLock)
200 {
201 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
202 {
203 dbcon.Open();
204
205 using (MySqlCommand result = new MySqlCommand(
206 "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon))
207 {
208 result.Parameters.AddWithValue("?uuid", user.ToString());
209 result.Parameters.AddWithValue("?zero", UUID.Zero.ToString());
210
211 using (MySqlDataReader reader = result.ExecuteReader())
212 {
213 List<InventoryFolderBase> items = new List<InventoryFolderBase>();
214 while (reader.Read())
215 items.Add(readInventoryFolder(reader));
216
217 InventoryFolderBase rootFolder = null;
218
219 // There should only ever be one root folder for a user. However, if there's more
220 // than one we'll simply use the first one rather than failing. It would be even
221 // nicer to print some message to this effect, but this feels like it's too low a
222 // to put such a message out, and it's too minor right now to spare the time to
223 // suitably refactor.
224 if (items.Count > 0)
225 rootFolder = items[0];
226
227 dbcon.Close();
228 return rootFolder;
229 }
230 }
231 }
232 }
233 }
234 catch (Exception e)
235 {
236 m_log.Error(e.Message, e);
237 return null;
238 }
239 }
240
241 /// <summary>
242 /// Return a list of folders in a users inventory contained within the specified folder.
243 /// This method is only used in tests - in normal operation the user always have one,
244 /// and only one, root folder.
245 /// </summary>
246 /// <param name="parentID">The folder to search</param>
247 /// <returns>A list of inventory folders</returns>
248 public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
249 {
250 try
251 {
252 lock (m_dbLock)
253 {
254 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
255 {
256 dbcon.Open();
257
258 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", dbcon))
259 {
260 result.Parameters.AddWithValue("?uuid", parentID.ToString());
261 using (MySqlDataReader reader = result.ExecuteReader())
262 {
263 List<InventoryFolderBase> items = new List<InventoryFolderBase>();
264
265 while (reader.Read())
266 items.Add(readInventoryFolder(reader));
267
268 dbcon.Close();
269 return items;
270 }
271 }
272 }
273 }
274 }
275 catch (Exception e)
276 {
277 m_log.Error(e.Message, e);
278 return null;
279 }
280 }
281
282 /// <summary>
283 /// Reads a one item from an SQL result
284 /// </summary>
285 /// <param name="reader">The SQL Result</param>
286 /// <returns>the item read</returns>
287 private static InventoryItemBase readInventoryItem(MySqlDataReader reader)
288 {
289 try
290 {
291 InventoryItemBase item = new InventoryItemBase();
292
293 // TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these.
294 // (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero)
295 item.CreatorId = reader["creatorID"].ToString();
296
297 // Be a bit safer in parsing these because the
298 // database doesn't enforce them to be not null, and
299 // the inventory still works if these are weird in the
300 // db
301
302 // (Empty is Ok, but "weird" will throw!)
303 item.Owner = DBGuid.FromDB(reader["avatarID"]);
304 item.GroupID = DBGuid.FromDB(reader["groupID"]);
305
306 // Rest of the parsing. If these UUID's fail, we're dead anyway
307 item.ID = DBGuid.FromDB(reader["inventoryID"]);
308 item.AssetID = DBGuid.FromDB(reader["assetID"]);
309 item.AssetType = (int) reader["assetType"];
310 item.Folder = DBGuid.FromDB(reader["parentFolderID"]);
311 item.Name = (string)(reader["inventoryName"] ?? String.Empty);
312 item.Description = (string)(reader["inventoryDescription"] ?? String.Empty);
313 item.NextPermissions = (uint) reader["inventoryNextPermissions"];
314 item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"];
315 item.InvType = (int) reader["invType"];
316 item.BasePermissions = (uint) reader["inventoryBasePermissions"];
317 item.EveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"];
318 item.GroupPermissions = (uint) reader["inventoryGroupPermissions"];
319 item.SalePrice = (int) reader["salePrice"];
320 item.SaleType = unchecked((byte)(Convert.ToSByte(reader["saleType"])));
321 item.CreationDate = (int) reader["creationDate"];
322 item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]);
323 item.Flags = (uint) reader["flags"];
324
325 return item;
326 }
327 catch (MySqlException e)
328 {
329 m_log.Error(e.ToString());
330 }
331
332 return null;
333 }
334
335 /// <summary>
336 /// Returns a specified inventory item
337 /// </summary>
338 /// <param name="item">The item to return</param>
339 /// <returns>An inventory item</returns>
340 public InventoryItemBase getInventoryItem(UUID itemID)
341 {
342 try
343 {
344 lock (m_dbLock)
345 {
346 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
347 {
348 dbcon.Open();
349
350 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", dbcon))
351 {
352 result.Parameters.AddWithValue("?uuid", itemID.ToString());
353
354 using (MySqlDataReader reader = result.ExecuteReader())
355 {
356 InventoryItemBase item = null;
357 if (reader.Read())
358 item = readInventoryItem(reader);
359
360 dbcon.Close();
361 return item;
362 }
363 }
364 }
365 }
366 }
367 catch (Exception e)
368 {
369 m_log.Error(e.Message, e);
370 }
371 return null;
372 }
373
374 /// <summary>
375 /// Reads a list of inventory folders returned by a query.
376 /// </summary>
377 /// <param name="reader">A MySQL Data Reader</param>
378 /// <returns>A List containing inventory folders</returns>
379 protected static InventoryFolderBase readInventoryFolder(MySqlDataReader reader)
380 {
381 try
382 {
383 InventoryFolderBase folder = new InventoryFolderBase();
384 folder.Owner = DBGuid.FromDB(reader["agentID"]);
385 folder.ParentID = DBGuid.FromDB(reader["parentFolderID"]);
386 folder.ID = DBGuid.FromDB(reader["folderID"]);
387 folder.Name = (string) reader["folderName"];
388 folder.Type = (short) reader["type"];
389 folder.Version = (ushort) ((int) reader["version"]);
390 return folder;
391 }
392 catch (Exception e)
393 {
394 m_log.Error(e.Message, e);
395 }
396
397 return null;
398 }
399
400
401 /// <summary>
402 /// Returns a specified inventory folder
403 /// </summary>
404 /// <param name="folderID">The folder to return</param>
405 /// <returns>A folder class</returns>
406 public InventoryFolderBase getInventoryFolder(UUID folderID)
407 {
408 try
409 {
410 lock (m_dbLock)
411 {
412 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
413 {
414 dbcon.Open();
415
416 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon))
417 {
418 result.Parameters.AddWithValue("?uuid", folderID.ToString());
419
420 using (MySqlDataReader reader = result.ExecuteReader())
421 {
422 InventoryFolderBase folder = null;
423 if (reader.Read())
424 folder = readInventoryFolder(reader);
425
426 dbcon.Close();
427 return folder;
428 }
429 }
430 }
431 }
432 }
433 catch (Exception e)
434 {
435 m_log.Error(e.Message, e);
436 return null;
437 }
438 }
439
440 /// <summary>
441 /// Adds a specified item to the database
442 /// </summary>
443 /// <param name="item">The inventory item</param>
444 public void addInventoryItem(InventoryItemBase item)
445 {
446 string sql =
447 "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName"
448 + ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType"
449 + ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, inventoryGroupPermissions, salePrice, saleType"
450 + ", creationDate, groupID, groupOwned, flags) VALUES ";
451 sql +=
452 "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription"
453 + ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID"
454 + ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?inventoryGroupPermissions, ?salePrice, ?saleType, ?creationDate"
455 + ", ?groupID, ?groupOwned, ?flags)";
456
457 string itemName = item.Name;
458 if (item.Name.Length > 64)
459 {
460 itemName = item.Name.Substring(0, 64);
461 m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item");
462 }
463
464 string itemDesc = item.Description;
465 if (item.Description.Length > 128)
466 {
467 itemDesc = item.Description.Substring(0, 128);
468 m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length + " to " + itemDesc.Length + " characters on add item");
469 }
470
471 try
472 {
473 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
474 {
475 dbcon.Open();
476
477 using (MySqlCommand result = new MySqlCommand(sql, dbcon))
478 {
479 result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
480 result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
481 result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
482 result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
483 result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
484 result.Parameters.AddWithValue("?inventoryName", itemName);
485 result.Parameters.AddWithValue("?inventoryDescription", itemDesc);
486 result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
487 result.Parameters.AddWithValue("?inventoryCurrentPermissions",
488 item.CurrentPermissions.ToString());
489 result.Parameters.AddWithValue("?invType", item.InvType);
490 result.Parameters.AddWithValue("?creatorID", item.CreatorId);
491 result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
492 result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
493 result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
494 result.Parameters.AddWithValue("?salePrice", item.SalePrice);
495 result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType));
496 result.Parameters.AddWithValue("?creationDate", item.CreationDate);
497 result.Parameters.AddWithValue("?groupID", item.GroupID);
498 result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
499 result.Parameters.AddWithValue("?flags", item.Flags);
500
501 lock (m_dbLock)
502 result.ExecuteNonQuery();
503
504 result.Dispose();
505 }
506
507 using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon))
508 {
509 result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
510
511 lock (m_dbLock)
512 result.ExecuteNonQuery();
513 }
514 dbcon.Close();
515 }
516 }
517 catch (MySqlException e)
518 {
519 m_log.Error(e.ToString());
520 }
521 }
522
523 /// <summary>
524 /// Updates the specified inventory item
525 /// </summary>
526 /// <param name="item">Inventory item to update</param>
527 public void updateInventoryItem(InventoryItemBase item)
528 {
529 addInventoryItem(item);
530 }
531
532 /// <summary>
533 /// Detele the specified inventory item
534 /// </summary>
535 /// <param name="item">The inventory item UUID to delete</param>
536 public void deleteInventoryItem(UUID itemID)
537 {
538 try
539 {
540 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
541 {
542 dbcon.Open();
543
544 using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon))
545 {
546 cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
547
548 lock (m_dbLock)
549 cmd.ExecuteNonQuery();
550 }
551 dbcon.Close();
552 }
553 }
554 catch (MySqlException e)
555 {
556 m_log.Error(e.Message, e);
557 }
558 }
559
560 public InventoryItemBase queryInventoryItem(UUID itemID)
561 {
562 return getInventoryItem(itemID);
563 }
564
565 public InventoryFolderBase queryInventoryFolder(UUID folderID)
566 {
567 return getInventoryFolder(folderID);
568 }
569
570 /// <summary>
571 /// Creates a new inventory folder
572 /// </summary>
573 /// <param name="folder">Folder to create</param>
574 public void addInventoryFolder(InventoryFolderBase folder)
575 {
576 string sql =
577 "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES ";
578 sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)";
579
580 string folderName = folder.Name;
581 if (folderName.Length > 64)
582 {
583 folderName = folderName.Substring(0, 64);
584 m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length + " to " + folderName.Length + " characters on add folder");
585 }
586
587 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
588 {
589 dbcon.Open();
590
591 using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
592 {
593 cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
594 cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
595 cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
596 cmd.Parameters.AddWithValue("?folderName", folderName);
597 cmd.Parameters.AddWithValue("?type", folder.Type);
598 cmd.Parameters.AddWithValue("?version", folder.Version);
599
600 try
601 {
602 lock (m_dbLock)
603 {
604 cmd.ExecuteNonQuery();
605 }
606 }
607 catch (Exception e)
608 {
609 m_log.Error(e.ToString());
610 }
611 }
612 dbcon.Close();
613 }
614 }
615
616 /// <summary>
617 /// Updates an inventory folder
618 /// </summary>
619 /// <param name="folder">Folder to update</param>
620 public void updateInventoryFolder(InventoryFolderBase folder)
621 {
622 addInventoryFolder(folder);
623 }
624
625 /// <summary>
626 /// Move an inventory folder
627 /// </summary>
628 /// <param name="folder">Folder to move</param>
629 /// <remarks>UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID</remarks>
630 public void moveInventoryFolder(InventoryFolderBase folder)
631 {
632 string sql =
633 "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID";
634
635 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
636 {
637 dbcon.Open();
638
639 using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
640 {
641 cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
642 cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
643
644 try
645 {
646 lock (m_dbLock)
647 {
648 cmd.ExecuteNonQuery();
649 }
650 }
651 catch (Exception e)
652 {
653 m_log.Error(e.ToString());
654 }
655 }
656 dbcon.Close();
657 }
658 }
659
660 /// <summary>
661 /// Append a list of all the child folders of a parent folder
662 /// </summary>
663 /// <param name="folders">list where folders will be appended</param>
664 /// <param name="parentID">ID of parent</param>
665 protected void getInventoryFolders(ref List<InventoryFolderBase> folders, UUID parentID)
666 {
667 List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID);
668
669 foreach (InventoryFolderBase f in subfolderList)
670 folders.Add(f);
671 }
672
673
674 /// <summary>
675 /// See IInventoryDataPlugin
676 /// </summary>
677 /// <param name="parentID"></param>
678 /// <returns></returns>
679 public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
680 {
681 /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one
682 * - We will only need to hit the database twice instead of n times.
683 * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned
684 * by the same person, each user only has 1 inventory heirarchy
685 * - The returned list is not ordered, instead of breadth-first ordered
686 There are basically 2 usage cases for getFolderHeirarchy:
687 1) Getting the user's entire inventory heirarchy when they log in
688 2) Finding a subfolder heirarchy to delete when emptying the trash.
689 This implementation will pull all inventory folders from the database, and then prune away any folder that
690 is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the
691 database than to make n requests. This pays off only if requested heirarchy is large.
692 By making this choice, we are making the worst case better at the cost of making the best case worse.
693 This way is generally better because we don't have to rebuild the connection/sql query per subfolder,
694 even if we end up getting more data from the SQL server than we need.
695 - Francis
696 */
697 try
698 {
699 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
700 Dictionary<UUID, List<InventoryFolderBase>> hashtable = new Dictionary<UUID, List<InventoryFolderBase>>(); ;
701 List<InventoryFolderBase> parentFolder = new List<InventoryFolderBase>();
702 bool buildResultsFromHashTable = false;
703
704 lock (m_dbLock)
705 {
706 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
707 {
708 dbcon.Open();
709
710 /* Fetch the parent folder from the database to determine the agent ID, and if
711 * we're querying the root of the inventory folder tree */
712 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon))
713 {
714 result.Parameters.AddWithValue("?uuid", parentID.ToString());
715
716 using (MySqlDataReader reader = result.ExecuteReader())
717 {
718 // Should be at most 1 result
719 while (reader.Read())
720 parentFolder.Add(readInventoryFolder(reader));
721 }
722 }
723
724 if (parentFolder.Count >= 1) // No result means parent folder does not exist
725 {
726 if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder
727 {
728 /* Get all of the agent's folders from the database, put them in a list and return it */
729 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon))
730 {
731 result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString());
732
733 using (MySqlDataReader reader = result.ExecuteReader())
734 {
735 while (reader.Read())
736 {
737 InventoryFolderBase curFolder = readInventoryFolder(reader);
738 if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list
739 folders.Add(curFolder);
740 }
741 }
742 }
743 } // if we are querying the root folder
744 else // else we are querying a subtree of the inventory folder tree
745 {
746 /* Get all of the agent's folders from the database, put them all in a hash table
747 * indexed by their parent ID */
748 using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon))
749 {
750 result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString());
751
752 using (MySqlDataReader reader = result.ExecuteReader())
753 {
754 while (reader.Read())
755 {
756 InventoryFolderBase curFolder = readInventoryFolder(reader);
757 if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling
758 hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list
759 else // else current folder has no known (yet) siblings
760 {
761 List<InventoryFolderBase> siblingList = new List<InventoryFolderBase>();
762 siblingList.Add(curFolder);
763 // Current folder has no known (yet) siblings
764 hashtable.Add(curFolder.ParentID, siblingList);
765 }
766 } // while more items to read from the database
767 }
768 }
769
770 // Set flag so we know we need to build the results from the hash table after
771 // we unlock the database
772 buildResultsFromHashTable = true;
773
774 } // else we are querying a subtree of the inventory folder tree
775 } // if folder parentID exists
776
777 if (buildResultsFromHashTable)
778 {
779 /* We have all of the user's folders stored in a hash table indexed by their parent ID
780 * and we need to return the requested subtree. We will build the requested subtree
781 * by performing a breadth-first-search on the hash table */
782 if (hashtable.ContainsKey(parentID))
783 folders.AddRange(hashtable[parentID]);
784 for (int i = 0; i < folders.Count; i++) // **Note: folders.Count is *not* static
785 if (hashtable.ContainsKey(folders[i].ID))
786 folders.AddRange(hashtable[folders[i].ID]);
787 }
788 }
789 } // lock (database)
790
791 return folders;
792 }
793 catch (Exception e)
794 {
795 m_log.Error(e.Message, e);
796 return null;
797 }
798 }
799
800 /// <summary>
801 /// Delete a folder from database
802 /// </summary>
803 /// <param name="folderID">the folder UUID</param>
804 protected void deleteOneFolder(UUID folderID)
805 {
806 try
807 {
808 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
809 {
810 dbcon.Open();
811
812 // System folders can never be deleted. Period.
813 using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid and type=-1", dbcon))
814 {
815 cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
816
817 lock (m_dbLock)
818 cmd.ExecuteNonQuery();
819 }
820 dbcon.Close();
821 }
822 }
823 catch (MySqlException e)
824 {
825 m_log.Error(e.Message, e);
826 }
827 }
828
829 /// <summary>
830 /// Delete all item in a folder
831 /// </summary>
832 /// <param name="folderID">the folder UUID</param>
833 protected void deleteItemsInFolder(UUID folderID)
834 {
835 try
836 {
837 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
838 {
839 dbcon.Open();
840
841 using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", dbcon))
842 {
843 cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
844
845 lock (m_dbLock)
846 cmd.ExecuteNonQuery();
847 }
848 dbcon.Close();
849 }
850 }
851 catch (MySqlException e)
852 {
853 m_log.Error(e.ToString());
854 }
855 }
856
857 /// <summary>
858 /// Deletes an inventory folder
859 /// </summary>
860 /// <param name="folderId">Id of folder to delete</param>
861 public void deleteInventoryFolder(UUID folderID)
862 {
863 List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
864
865 //Delete all sub-folders
866 foreach (InventoryFolderBase f in subFolders)
867 {
868 deleteOneFolder(f.ID);
869 deleteItemsInFolder(f.ID);
870 }
871
872 //Delete the actual row
873 deleteOneFolder(folderID);
874 deleteItemsInFolder(folderID);
875 }
876
877 public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
878 {
879 lock (m_dbLock)
880 {
881 try
882 {
883 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
884 {
885 dbcon.Open();
886
887 using (MySqlCommand sqlCmd = new MySqlCommand(
888 "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags & 1", dbcon))
889 {
890 sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString());
891 sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
892
893 using (MySqlDataReader result = sqlCmd.ExecuteReader())
894 {
895 List<InventoryItemBase> list = new List<InventoryItemBase>();
896 while (result.Read())
897 {
898 InventoryItemBase item = readInventoryItem(result);
899 if (item != null)
900 list.Add(item);
901 }
902 dbcon.Close();
903 return list;
904 }
905 }
906 }
907 }
908 catch (Exception e)
909 {
910 m_log.Error(e.Message, e);
911 return null;
912 }
913 }
914 }
915 }
916}
diff --git a/OpenSim/Data/MySQL/MySQLMigrations.cs b/OpenSim/Data/MySQL/MySQLMigrations.cs
new file mode 100644
index 0000000..2043dae
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLMigrations.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.Generic;
30using System.Data;
31using System.Data.Common;
32using System.IO;
33using System.Reflection;
34using System.Text.RegularExpressions;
35using log4net;
36using MySql.Data.MySqlClient;
37
38namespace OpenSim.Data.MySQL
39{
40 /// <summary>This is a MySQL-customized migration processor. The only difference is in how
41 /// it executes SQL scripts (using MySqlScript instead of MyCommand)
42 ///
43 /// </summary>
44 public class MySqlMigration : Migration
45 {
46 public MySqlMigration()
47 : base()
48 {
49 }
50
51 public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) :
52 base(conn, assem, subtype, type)
53 {
54 }
55
56 public MySqlMigration(DbConnection conn, Assembly assem, string type) :
57 base(conn, assem, type)
58 {
59 }
60
61 protected override void ExecuteScript(DbConnection conn, string[] script)
62 {
63 if (!(conn is MySqlConnection))
64 {
65 base.ExecuteScript(conn, script);
66 return;
67 }
68
69 MySqlScript scr = new MySqlScript((MySqlConnection)conn);
70 {
71 foreach (string sql in script)
72 {
73 scr.Query = sql;
74 scr.Error += delegate(object sender, MySqlScriptErrorEventArgs args)
75 {
76 throw new Exception(sql);
77 };
78 scr.Execute();
79 }
80 }
81 }
82 }
83}
diff --git a/OpenSim/Data/MySQL/MySQLMuteListData.cs b/OpenSim/Data/MySQL/MySQLMuteListData.cs
new file mode 100644
index 0000000..a5935a3
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLMuteListData.cs
@@ -0,0 +1,67 @@
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 MySqlMuteListData : MySQLGenericTableHandler<MuteData>, IMuteListData
39 {
40 public MySqlMuteListData(string connectionString)
41 : base(connectionString, "MuteList", "MuteListStore")
42 {
43 }
44
45 public MuteData[] Get(UUID agentID)
46 {
47 MuteData[] data = base.Get("AgentID", agentID.ToString());
48 return data;
49 }
50
51 public bool Delete(UUID agentID, UUID muteID, string muteName)
52 {
53 string cmnd ="delete from MuteList where AgentID = ?AgentID and MuteID = ?MuteID and MuteName = ?MuteName";
54
55 using (MySqlCommand cmd = new MySqlCommand(cmnd))
56 {
57 cmd.Parameters.AddWithValue("?AgentID", agentID.ToString());
58 cmd.Parameters.AddWithValue("?MuteID", muteID.ToString());
59 cmd.Parameters.AddWithValue("?MuteName", muteName);
60
61 if (ExecuteNonQuery(cmd) > 0)
62 return true;
63 return false;
64 }
65 }
66 }
67} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLOfflineIMData.cs b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs
new file mode 100644
index 0000000..7608858
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs
@@ -0,0 +1,59 @@
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;
32
33using OpenSim.Framework;
34using OpenSim.Data.MySQL;
35
36using OpenMetaverse;
37using MySql.Data.MySqlClient;
38
39namespace OpenSim.Data.MySQL
40{
41 public class MySQLOfflineIMData : MySQLGenericTableHandler<OfflineIMData>, IOfflineIMData
42 {
43 public MySQLOfflineIMData(string connectionString, string realm)
44 : base(connectionString, realm, "IM_Store")
45 {
46 }
47
48 public void DeleteOld()
49 {
50 using (MySqlCommand cmd = new MySqlCommand())
51 {
52 cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
53
54 ExecuteNonQuery(cmd);
55 }
56
57 }
58 }
59}
diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs
new file mode 100644
index 0000000..b9114eb
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs
@@ -0,0 +1,122 @@
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", sessionID.ToString());
56
57 if (ret.Length == 0)
58 return null;
59
60 return ret[0];
61 }
62
63 public PresenceData GetByUser(UUID userID)
64 {
65 PresenceData[] ret = Get("UserID", userID.ToString());
66
67 if (ret.Length == 0)
68 return null;
69
70 return ret[0];
71 }
72
73 public void LogoutRegionAgents(UUID regionID)
74 {
75 using (MySqlCommand cmd = new MySqlCommand())
76 {
77 cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
78
79 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
80
81 ExecuteNonQuery(cmd);
82 }
83 }
84
85 public bool ReportAgent(UUID sessionID, UUID regionID)
86 {
87 PresenceData[] pd = Get("SessionID", sessionID.ToString());
88 if (pd.Length == 0)
89 return false;
90
91 if (regionID == UUID.Zero)
92 return false;
93
94 using (MySqlCommand cmd = new MySqlCommand())
95 {
96 cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
97
98 cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
99 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
100
101 if (ExecuteNonQuery(cmd) == 0)
102 return false;
103 }
104
105 return true;
106 }
107
108 public bool VerifyAgent(UUID agentId, UUID secureSessionID)
109 {
110 PresenceData[] ret = Get("SecureSessionID",
111 secureSessionID.ToString());
112
113 if (ret.Length == 0)
114 return false;
115
116 if(ret[0].UserID != agentId.ToString())
117 return false;
118
119 return true;
120 }
121 }
122} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLRaw.cs b/OpenSim/Data/MySQL/MySQLRaw.cs
new file mode 100644
index 0000000..bb8c96c
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLRaw.cs
@@ -0,0 +1,197 @@
1// https://dev.mysql.com/doc/connector-net/en/
2
3
4using System;
5using System.Collections;
6using System.Collections.Generic;
7using System.Data;
8using System.Reflection;
9using System.Text;
10using log4net;
11using MySql.Data.MySqlClient;
12
13namespace OpenSim.Data.MySQL
14{
15 public class MySQLRaw
16 {
17 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
18 private string m_connectString;
19
20 public MySQLRaw(string connect)
21 {
22 m_connectString = connect;
23 }
24
25 public int Count(string table)
26 {
27 return Count(table, "");
28 }
29 public int Count(string table, string wher)
30 {
31 string query = "SELECT Count(*) FROM " + table;
32 if ("" != wher)
33 query = query + " WHERE " + wher;
34 int result = -1;
35
36 object r = doScalarQuery(query);
37 if (r != null)
38 result = Convert.ToInt32(r);
39
40 return result;
41 }
42
43 public List< Hashtable > Join(string table, string select, string join, string wher, string order)
44 {
45 if ("" == select)
46 select = "*";
47 string query = "SELECT " + select + " FROM " + table;
48 if ("" != join)
49 query = query + " " + join;
50 if ("" != wher)
51 query = query + " WHERE " + wher;
52 if ("" != order)
53 query = query + " ORDER BY " + order;
54
55 using (MySqlConnection dbcon = new MySqlConnection(m_connectString))
56 {
57 dbcon.Open();
58 MySqlCommand cmd = new MySqlCommand(query, dbcon);
59 MySqlDataReader rdr = cmd.ExecuteReader();
60 List<string> names = new List<string>();
61 DataTable schema = rdr.GetSchemaTable();
62 List< Hashtable > list = new List< Hashtable >();
63
64 foreach (DataRow row in schema.Rows)
65 {
66 string tbl = "";
67 string nm = "";
68 string tp = "";
69 foreach (DataColumn col in schema.Columns)
70 {
71 if ("BaseTableName" == col.ColumnName) tbl = row[col].ToString();
72 if ("ColumnName" == col.ColumnName) nm = row[col].ToString();
73 if ("DataType" == col.ColumnName) tp = row[col].ToString();
74 }
75 names.Add(nm);
76 }
77
78 while (rdr.Read())
79 {
80 Hashtable r = new Hashtable();
81 foreach (string name in names)
82 {
83 r[name] = rdr[name];
84 }
85 list.Add(r);
86 }
87
88 rdr.Close();
89 dbcon.Close();
90 return list;
91 }
92 }
93
94 public List< Hashtable > Select(string table, string select, string wher, string order)
95 {
96 if ("" == select)
97 select = "*";
98 string query = "SELECT " + select + " FROM " + table;
99 if ("" != wher)
100 query = query + " WHERE " + wher;
101 if ("" != order)
102 query = query + " ORDER BY " + order;
103
104 using (MySqlConnection dbcon = new MySqlConnection(m_connectString))
105 {
106 dbcon.Open();
107 MySqlCommand cmd = new MySqlCommand(query, dbcon);
108 MySqlDataReader rdr = cmd.ExecuteReader();
109 List<string> names = new List<string>();
110 DataTable schema = rdr.GetSchemaTable();
111 List< Hashtable > list = new List< Hashtable >();
112
113 foreach (DataRow row in schema.Rows)
114 {
115 string tbl = "";
116 string nm = "";
117 string tp = "";
118 foreach (DataColumn col in schema.Columns)
119 {
120 if ("BaseTableName" == col.ColumnName) tbl = row[col].ToString();
121 if ("ColumnName" == col.ColumnName) nm = row[col].ToString();
122 if ("DataType" == col.ColumnName) tp = row[col].ToString();
123 }
124 names.Add(nm);
125 }
126
127 while (rdr.Read())
128 {
129 Hashtable r = new Hashtable();
130 foreach (string name in names)
131 {
132 r[name] = rdr[name];
133 }
134 list.Add(r);
135 }
136
137 rdr.Close();
138 dbcon.Close();
139 return list;
140 }
141 }
142
143 private object doScalarQuery(string query)
144 {
145 try
146 {
147 using (MySqlConnection dbcon = new MySqlConnection(m_connectString))
148 {
149 dbcon.Open();
150 MySqlCommand cmd = new MySqlCommand(query, dbcon);
151 Object ret = cmd.ExecuteScalar();
152 dbcon.Close();
153 return ret;
154 }
155 }
156 catch (MySqlException e)
157 {
158 m_log.ErrorFormat("[MYSQL RAW]: Problem connecting to the database {0}", e.Message);
159 return null;
160 }
161 }
162
163 private void doNonQuery(string query)
164 {
165 using (MySqlConnection dbcon = new MySqlConnection(m_connectString))
166 {
167 dbcon.Open();
168 MySqlCommand cmd = new MySqlCommand(query, dbcon);
169 cmd.ExecuteNonQuery();
170 dbcon.Close();
171 }
172 }
173
174 public void Insert(string table)
175 {
176 string query = "INSERT INTO " + table + " (name, age) VALUES('John Smith', '33')";
177 doNonQuery(query);
178 }
179
180 public void Update(string table, string wher)
181 {
182 string query = "UPDATE " + table + " SET name='Joe', age='22'";
183 if ("" != wher)
184 query = query + " WHERE " + wher;
185 doNonQuery(query);
186 }
187
188 public void Delete(string table, string wher)
189 {
190 string query = "DELETE FROM " + table;
191 if ("" != wher)
192 query = query + " WHERE " + wher;
193 doNonQuery(query);
194 }
195
196 }
197}
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs
new file mode 100644
index 0000000..46df421
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLRegionData.cs
@@ -0,0 +1,421 @@
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 MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Data;
37using RegionFlags = OpenSim.Framework.RegionFlags;
38
39namespace OpenSim.Data.MySQL
40{
41 public class MySqlRegionData : MySqlFramework, IRegionData
42 {
43 private string m_Realm;
44 private List<string> m_ColumnNames;
45 //private string m_connectionString;
46
47 protected virtual Assembly Assembly
48 {
49 get { return GetType().Assembly; }
50 }
51
52 public MySqlRegionData(string connectionString, string realm)
53 : base(connectionString)
54 {
55 m_Realm = realm;
56 m_connectionString = connectionString;
57
58 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
59 {
60 dbcon.Open();
61 Migration m = new Migration(dbcon, Assembly, "GridStore");
62 m.Update();
63 dbcon.Close();
64 }
65 }
66
67 public List<RegionData> Get(string regionName, UUID scopeID)
68 {
69 string command = "select * from `"+m_Realm+"` where regionName like ?regionName";
70 if (scopeID != UUID.Zero)
71 command += " and ScopeID = ?scopeID";
72
73 command += " order by regionName";
74
75 using (MySqlCommand cmd = new MySqlCommand(command))
76 {
77 cmd.Parameters.AddWithValue("?regionName", regionName);
78 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
79
80 return RunCommand(cmd);
81 }
82 }
83
84 public RegionData Get(int posX, int posY, UUID scopeID)
85 {
86/* fixed size regions
87 string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY";
88 if (scopeID != UUID.Zero)
89 command += " and ScopeID = ?scopeID";
90
91 using (MySqlCommand cmd = new MySqlCommand(command))
92 {
93 cmd.Parameters.AddWithValue("?posX", posX.ToString());
94 cmd.Parameters.AddWithValue("?posY", posY.ToString());
95 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
96
97 List<RegionData> ret = RunCommand(cmd);
98 if (ret.Count == 0)
99 return null;
100
101 return ret[0];
102 }
103*/
104 // extend database search for maximum region size area
105 string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
106 if (scopeID != UUID.Zero)
107 command += " and ScopeID = ?scopeID";
108
109 int startX = posX - (int)Constants.MaximumRegionSize;
110 int startY = posY - (int)Constants.MaximumRegionSize;
111 int endX = posX;
112 int endY = posY;
113
114 List<RegionData> ret;
115 using (MySqlCommand cmd = new MySqlCommand(command))
116 {
117 cmd.Parameters.AddWithValue("?startX", startX.ToString());
118 cmd.Parameters.AddWithValue("?startY", startY.ToString());
119 cmd.Parameters.AddWithValue("?endX", endX.ToString());
120 cmd.Parameters.AddWithValue("?endY", endY.ToString());
121 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
122
123 ret = RunCommand(cmd);
124 }
125
126 if (ret.Count == 0)
127 return null;
128
129 // find the first that contains pos
130 RegionData rg = null;
131 foreach (RegionData r in ret)
132 {
133 if (posX >= r.posX && posX < r.posX + r.sizeX
134 && posY >= r.posY && posY < r.posY + r.sizeY)
135 {
136 rg = r;
137 break;
138 }
139 }
140
141 return rg;
142 }
143
144 public RegionData Get(UUID regionID, UUID scopeID)
145 {
146 string command = "select * from `"+m_Realm+"` where uuid = ?regionID";
147 if (scopeID != UUID.Zero)
148 command += " and ScopeID = ?scopeID";
149
150 using (MySqlCommand cmd = new MySqlCommand(command))
151 {
152 cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
153 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
154
155 List<RegionData> ret = RunCommand(cmd);
156 if (ret.Count == 0)
157 return null;
158
159 return ret[0];
160 }
161 }
162
163 public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
164 {
165/* fix size regions
166 string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
167 if (scopeID != UUID.Zero)
168 command += " and ScopeID = ?scopeID";
169
170 using (MySqlCommand cmd = new MySqlCommand(command))
171 {
172 cmd.Parameters.AddWithValue("?startX", startX.ToString());
173 cmd.Parameters.AddWithValue("?startY", startY.ToString());
174 cmd.Parameters.AddWithValue("?endX", endX.ToString());
175 cmd.Parameters.AddWithValue("?endY", endY.ToString());
176 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
177
178 return RunCommand(cmd);
179 }
180 */
181 string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
182 if (scopeID != UUID.Zero)
183 command += " and ScopeID = ?scopeID";
184
185 int qstartX = startX - (int)Constants.MaximumRegionSize;
186 int qstartY = startY - (int)Constants.MaximumRegionSize;
187
188 List<RegionData> dbret;
189 using (MySqlCommand cmd = new MySqlCommand(command))
190 {
191 cmd.Parameters.AddWithValue("?startX", qstartX.ToString());
192 cmd.Parameters.AddWithValue("?startY", qstartY.ToString());
193 cmd.Parameters.AddWithValue("?endX", endX.ToString());
194 cmd.Parameters.AddWithValue("?endY", endY.ToString());
195 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
196
197 dbret = RunCommand(cmd);
198 }
199
200 List<RegionData> ret = new List<RegionData>();
201
202 if (dbret.Count == 0)
203 return ret;
204
205 foreach (RegionData r in dbret)
206 {
207 if (r.posX + r.sizeX > startX && r.posX <= endX
208 && r.posY + r.sizeY > startY && r.posY <= endY)
209 ret.Add(r);
210 }
211 return ret;
212 }
213
214 public List<RegionData> RunCommand(MySqlCommand cmd)
215 {
216 List<RegionData> retList = new List<RegionData>();
217
218 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
219 {
220 dbcon.Open();
221 cmd.Connection = dbcon;
222
223 using (IDataReader result = cmd.ExecuteReader())
224 {
225 while (result.Read())
226 {
227 RegionData ret = new RegionData();
228 ret.Data = new Dictionary<string, object>();
229
230 ret.RegionID = DBGuid.FromDB(result["uuid"]);
231 ret.ScopeID = DBGuid.FromDB(result["ScopeID"]);
232
233 ret.RegionName = result["regionName"].ToString();
234 ret.posX = Convert.ToInt32(result["locX"]);
235 ret.posY = Convert.ToInt32(result["locY"]);
236 ret.sizeX = Convert.ToInt32(result["sizeX"]);
237 ret.sizeY = Convert.ToInt32(result["sizeY"]);
238
239 CheckColumnNames(result);
240
241 foreach (string s in m_ColumnNames)
242 {
243 if (s == "uuid")
244 continue;
245 if (s == "ScopeID")
246 continue;
247 if (s == "regionName")
248 continue;
249 if (s == "locX")
250 continue;
251 if (s == "locY")
252 continue;
253
254 object value = result[s];
255 if (value is DBNull)
256 ret.Data[s] = null;
257 else
258 ret.Data[s] = result[s].ToString();
259 }
260
261 retList.Add(ret);
262 }
263 }
264 cmd.Connection = null;
265 dbcon.Close();
266 }
267
268 return retList;
269 }
270
271 private void CheckColumnNames(IDataReader result)
272 {
273 if (m_ColumnNames != null)
274 return;
275
276 List<string> columnNames = new List<string>();
277
278 DataTable schemaTable = result.GetSchemaTable();
279 foreach (DataRow row in schemaTable.Rows)
280 {
281 if (row["ColumnName"] != null)
282 columnNames.Add(row["ColumnName"].ToString());
283 }
284
285 m_ColumnNames = columnNames;
286 }
287
288 public bool Store(RegionData data)
289 {
290 if (data.Data.ContainsKey("uuid"))
291 data.Data.Remove("uuid");
292 if (data.Data.ContainsKey("ScopeID"))
293 data.Data.Remove("ScopeID");
294 if (data.Data.ContainsKey("regionName"))
295 data.Data.Remove("regionName");
296 if (data.Data.ContainsKey("posX"))
297 data.Data.Remove("posX");
298 if (data.Data.ContainsKey("posY"))
299 data.Data.Remove("posY");
300 if (data.Data.ContainsKey("sizeX"))
301 data.Data.Remove("sizeX");
302 if (data.Data.ContainsKey("sizeY"))
303 data.Data.Remove("sizeY");
304 if (data.Data.ContainsKey("locX"))
305 data.Data.Remove("locX");
306 if (data.Data.ContainsKey("locY"))
307 data.Data.Remove("locY");
308
309 if (data.RegionName.Length > 128)
310 data.RegionName = data.RegionName.Substring(0, 128);
311
312 string[] fields = new List<string>(data.Data.Keys).ToArray();
313
314 using (MySqlCommand cmd = new MySqlCommand())
315 {
316 string update = "update `" + m_Realm + "` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY";
317 foreach (string field in fields)
318 {
319 update += ", ";
320 update += "`" + field + "` = ?" + field;
321
322 cmd.Parameters.AddWithValue("?" + field, data.Data[field]);
323 }
324
325 update += " where uuid = ?regionID";
326
327 if (data.ScopeID != UUID.Zero)
328 update += " and ScopeID = ?scopeID";
329
330 cmd.CommandText = update;
331 cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString());
332 cmd.Parameters.AddWithValue("?regionName", data.RegionName);
333 cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString());
334 cmd.Parameters.AddWithValue("?posX", data.posX.ToString());
335 cmd.Parameters.AddWithValue("?posY", data.posY.ToString());
336 cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString());
337 cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString());
338
339 if (ExecuteNonQuery(cmd) < 1)
340 {
341 string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" +
342 String.Join("`, `", fields) +
343 "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")";
344
345 cmd.CommandText = insert;
346
347 if (ExecuteNonQuery(cmd) < 1)
348 {
349 return false;
350 }
351 }
352 }
353
354 return true;
355 }
356
357 public bool SetDataItem(UUID regionID, string item, string value)
358 {
359 using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where uuid = ?UUID"))
360 {
361 cmd.Parameters.AddWithValue("?" + item, value);
362 cmd.Parameters.AddWithValue("?UUID", regionID.ToString());
363
364 if (ExecuteNonQuery(cmd) > 0)
365 return true;
366 }
367
368 return false;
369 }
370
371 public bool Delete(UUID regionID)
372 {
373 using (MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + "` where uuid = ?UUID"))
374 {
375 cmd.Parameters.AddWithValue("?UUID", regionID.ToString());
376
377 if (ExecuteNonQuery(cmd) > 0)
378 return true;
379 }
380
381 return false;
382 }
383
384 public List<RegionData> GetDefaultRegions(UUID scopeID)
385 {
386 return Get((int)RegionFlags.DefaultRegion, scopeID);
387 }
388
389 public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
390 {
391 return Get((int)RegionFlags.DefaultHGRegion, scopeID);
392 }
393
394 public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
395 {
396 List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
397 RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y);
398 regions.Sort(distanceComparer);
399 return regions;
400 }
401
402 public List<RegionData> GetHyperlinks(UUID scopeID)
403 {
404 return Get((int)RegionFlags.Hyperlink, scopeID);
405 }
406
407 private List<RegionData> Get(int regionFlags, UUID scopeID)
408 {
409 string command = "select * from `" + m_Realm + "` where (flags & " + regionFlags.ToString() + ") <> 0";
410 if (scopeID != UUID.Zero)
411 command += " and ScopeID = ?scopeID";
412
413 using (MySqlCommand cmd = new MySqlCommand(command))
414 {
415 cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
416
417 return RunCommand(cmd);
418 }
419 }
420 }
421} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
new file mode 100644
index 0000000..e754522
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -0,0 +1,2337 @@
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 System.Threading;
35using log4net;
36using MySql.Data.MySqlClient;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Data;
42
43namespace OpenSim.Data.MySQL
44{
45 /// <summary>
46 /// A MySQL Interface for the Region Server
47 /// </summary>
48 public class MySQLSimulationData : ISimulationDataStore
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader = "[REGION DB MYSQL]";
52
53 private string m_connectionString;
54
55 /// <summary>
56 /// This lock was being used to serialize database operations when the connection was shared, but this has
57 /// been unnecessary for a long time after we switched to using MySQL's underlying connection pooling instead.
58 /// FIXME: However, the locks remain in many places since they are effectively providing a level of
59 /// transactionality. This should be replaced by more efficient database transactions which would not require
60 /// unrelated operations to block each other or unrelated operations on the same tables from blocking each
61 /// other.
62 /// </summary>
63 private object m_dbLock = new object();
64
65 protected virtual Assembly Assembly
66 {
67 get { return GetType().Assembly; }
68 }
69
70 public MySQLSimulationData()
71 {
72 }
73
74 public MySQLSimulationData(string connectionString)
75 {
76 Initialise(connectionString);
77 }
78
79 public virtual void Initialise(string connectionString)
80 {
81 m_connectionString = connectionString;
82
83 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
84 {
85 dbcon.Open();
86
87 // Apply new Migrations
88 //
89 Migration m = new Migration(dbcon, Assembly, "RegionStore");
90 m.Update();
91 dbcon.Close();
92 }
93 }
94
95 private IDataReader ExecuteReader(MySqlCommand c)
96 {
97 IDataReader r = null;
98
99 try
100 {
101 r = c.ExecuteReader();
102 }
103 catch (Exception e)
104 {
105 m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e);
106 throw;
107 }
108
109 return r;
110 }
111
112 private void ExecuteNonQuery(MySqlCommand c)
113 {
114 try
115 {
116 c.ExecuteNonQuery();
117 }
118 catch (Exception e)
119 {
120 m_log.Error("[REGION DB]: MySQL error in ExecuteNonQuery: " + e.Message);
121 throw;
122 }
123 }
124
125 public void Dispose() {}
126
127 public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID)
128 {
129 uint flags = obj.RootPart.GetEffectiveObjectFlags();
130
131 // Eligibility check
132 //
133 // PrimFlags.Temporary is not used in OpenSim code and cannot
134 // be guaranteed to always be clear. Don't check it.
135// if ((flags & (uint)PrimFlags.Temporary) != 0)
136// return;
137 if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
138 return;
139
140 lock (m_dbLock)
141 {
142 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
143 {
144 dbcon.Open();
145
146 using (MySqlCommand cmd = dbcon.CreateCommand())
147 {
148 foreach (SceneObjectPart prim in obj.Parts)
149 {
150 cmd.Parameters.Clear();
151
152 cmd.CommandText = "replace into prims (" +
153 "UUID, CreationDate, " +
154 "Name, Text, Description, " +
155 "SitName, TouchName, ObjectFlags, " +
156 "OwnerMask, NextOwnerMask, GroupMask, " +
157 "EveryoneMask, BaseMask, PositionX, " +
158 "PositionY, PositionZ, GroupPositionX, " +
159 "GroupPositionY, GroupPositionZ, VelocityX, " +
160 "VelocityY, VelocityZ, AngularVelocityX, " +
161 "AngularVelocityY, AngularVelocityZ, " +
162 "AccelerationX, AccelerationY, " +
163 "AccelerationZ, RotationX, " +
164 "RotationY, RotationZ, " +
165 "RotationW, SitTargetOffsetX, " +
166 "SitTargetOffsetY, SitTargetOffsetZ, " +
167 "SitTargetOrientW, SitTargetOrientX, " +
168 "SitTargetOrientY, SitTargetOrientZ, " +
169 "RegionUUID, CreatorID, " +
170 "OwnerID, GroupID, " +
171 "LastOwnerID, RezzerID, SceneGroupID, " +
172 "PayPrice, PayButton1, " +
173 "PayButton2, PayButton3, " +
174 "PayButton4, LoopedSound, " +
175 "LoopedSoundGain, TextureAnimation, " +
176 "OmegaX, OmegaY, OmegaZ, " +
177 "CameraEyeOffsetX, CameraEyeOffsetY, " +
178 "CameraEyeOffsetZ, CameraAtOffsetX, " +
179 "CameraAtOffsetY, CameraAtOffsetZ, " +
180 "ForceMouselook, ScriptAccessPin, " +
181 "AllowedDrop, DieAtEdge, " +
182 "SalePrice, SaleType, " +
183 "ColorR, ColorG, ColorB, ColorA, " +
184 "ParticleSystem, ClickAction, Material, " +
185 "CollisionSound, CollisionSoundVolume, " +
186 "PassTouches, " +
187 "PassCollisions, " +
188 "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " +
189 "AttachedPosY, AttachedPosZ, " +
190 "PhysicsShapeType, Density, GravityModifier, " +
191 "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " +
192 "RotationAxisLocks" +
193 ") values (" + "?UUID, " +
194 "?CreationDate, ?Name, ?Text, " +
195 "?Description, ?SitName, ?TouchName, " +
196 "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
197 "?GroupMask, ?EveryoneMask, ?BaseMask, " +
198 "?PositionX, ?PositionY, ?PositionZ, " +
199 "?GroupPositionX, ?GroupPositionY, " +
200 "?GroupPositionZ, ?VelocityX, " +
201 "?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
202 "?AngularVelocityY, ?AngularVelocityZ, " +
203 "?AccelerationX, ?AccelerationY, " +
204 "?AccelerationZ, ?RotationX, " +
205 "?RotationY, ?RotationZ, " +
206 "?RotationW, ?SitTargetOffsetX, " +
207 "?SitTargetOffsetY, ?SitTargetOffsetZ, " +
208 "?SitTargetOrientW, ?SitTargetOrientX, " +
209 "?SitTargetOrientY, ?SitTargetOrientZ, " +
210 "?RegionUUID, ?CreatorID, ?OwnerID, " +
211 "?GroupID, ?LastOwnerID, ?RezzerID, ?SceneGroupID, " +
212 "?PayPrice, ?PayButton1, ?PayButton2, " +
213 "?PayButton3, ?PayButton4, ?LoopedSound, " +
214 "?LoopedSoundGain, ?TextureAnimation, " +
215 "?OmegaX, ?OmegaY, ?OmegaZ, " +
216 "?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
217 "?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
218 "?CameraAtOffsetY, ?CameraAtOffsetZ, " +
219 "?ForceMouselook, ?ScriptAccessPin, " +
220 "?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
221 "?SaleType, ?ColorR, ?ColorG, " +
222 "?ColorB, ?ColorA, ?ParticleSystem, " +
223 "?ClickAction, ?Material, ?CollisionSound, " +
224 "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " +
225 "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " +
226 "?AttachedPosY, ?AttachedPosZ, " +
227 "?PhysicsShapeType, ?Density, ?GravityModifier, " +
228 "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," +
229 "?RotationAxisLocks)";
230
231 FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
232
233 ExecuteNonQuery(cmd);
234
235 cmd.Parameters.Clear();
236
237 cmd.CommandText = "replace into primshapes (" +
238 "UUID, Shape, ScaleX, ScaleY, " +
239 "ScaleZ, PCode, PathBegin, PathEnd, " +
240 "PathScaleX, PathScaleY, PathShearX, " +
241 "PathShearY, PathSkew, PathCurve, " +
242 "PathRadiusOffset, PathRevolutions, " +
243 "PathTaperX, PathTaperY, PathTwist, " +
244 "PathTwistBegin, ProfileBegin, ProfileEnd, " +
245 "ProfileCurve, ProfileHollow, Texture, " +
246 "ExtraParams, State, LastAttachPoint, Media) " +
247 "values (?UUID, " +
248 "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
249 "?PCode, ?PathBegin, ?PathEnd, " +
250 "?PathScaleX, ?PathScaleY, " +
251 "?PathShearX, ?PathShearY, " +
252 "?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
253 "?PathRevolutions, ?PathTaperX, " +
254 "?PathTaperY, ?PathTwist, " +
255 "?PathTwistBegin, ?ProfileBegin, " +
256 "?ProfileEnd, ?ProfileCurve, " +
257 "?ProfileHollow, ?Texture, ?ExtraParams, " +
258 "?State, ?LastAttachPoint, ?Media)";
259
260 FillShapeCommand(cmd, prim);
261
262 ExecuteNonQuery(cmd);
263 }
264 }
265 dbcon.Close();
266 }
267 }
268 }
269
270 public virtual void RemoveObject(UUID obj, UUID regionUUID)
271 {
272// m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID);
273
274 List<UUID> uuids = new List<UUID>();
275
276 // Formerly, this used to check the region UUID.
277 // That makes no sense, as we remove the contents of a prim
278 // unconditionally, but the prim dependent on the region ID.
279 // So, we would destroy an object and cause hard to detect
280 // issues if we delete the contents only. Deleting it all may
281 // cause the loss of a prim, but is cleaner.
282 // It's also faster because it uses the primary key.
283 //
284 lock (m_dbLock)
285 {
286 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
287 {
288 dbcon.Open();
289
290 using (MySqlCommand cmd = dbcon.CreateCommand())
291 {
292 cmd.CommandText = "select UUID from prims where SceneGroupID= ?UUID";
293 cmd.Parameters.AddWithValue("UUID", obj.ToString());
294
295 using (IDataReader reader = ExecuteReader(cmd))
296 {
297 while (reader.Read())
298 uuids.Add(DBGuid.FromDB(reader["UUID"].ToString()));
299 }
300
301 // delete the main prims
302 cmd.CommandText = "delete from prims where SceneGroupID= ?UUID";
303 ExecuteNonQuery(cmd);
304 }
305 dbcon.Close();
306 }
307 }
308
309 // there is no way this should be < 1 unless there is
310 // a very corrupt database, but in that case be extra
311 // safe anyway.
312 if (uuids.Count > 0)
313 {
314 RemoveShapes(uuids);
315 RemoveItems(uuids);
316 }
317 }
318
319 /// <summary>
320 /// Remove all persisted items of the given prim.
321 /// The caller must acquire the necessrary synchronization locks
322 /// </summary>
323 /// <param name="uuid">the Item UUID</param>
324 private void RemoveItems(UUID uuid)
325 {
326 // locked by caller
327// lock (m_dbLock)
328 {
329 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
330 {
331 dbcon.Open();
332
333 using (MySqlCommand cmd = dbcon.CreateCommand())
334 {
335 cmd.CommandText = "delete from primitems where PrimID = ?PrimID";
336 cmd.Parameters.AddWithValue("PrimID", uuid.ToString());
337
338 ExecuteNonQuery(cmd);
339 }
340 dbcon.Close();
341 }
342 }
343 }
344
345 /// <summary>
346 /// Remove all persisted shapes for a list of prims
347 /// The caller must acquire the necessrary synchronization locks
348 /// </summary>
349 /// <param name="uuids">the list of UUIDs</param>
350 private void RemoveShapes(List<UUID> uuids)
351 {
352 lock (m_dbLock)
353 {
354 string sql = "delete from primshapes where ";
355 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
356 {
357 dbcon.Open();
358
359 using (MySqlCommand cmd = dbcon.CreateCommand())
360 {
361 for (int i = 0; i < uuids.Count; i++)
362 {
363 if ((i + 1) == uuids.Count)
364 {// end of the list
365 sql += "(UUID = ?UUID" + i + ")";
366 }
367 else
368 {
369 sql += "(UUID = ?UUID" + i + ") or ";
370 }
371 }
372 cmd.CommandText = sql;
373
374 for (int i = 0; i < uuids.Count; i++)
375 cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString());
376
377 ExecuteNonQuery(cmd);
378 }
379 dbcon.Close();
380 }
381 }
382 }
383
384 /// <summary>
385 /// Remove all persisted items for a list of prims
386 /// The caller must acquire the necessrary synchronization locks
387 /// </summary>
388 /// <param name="uuids">the list of UUIDs</param>
389 private void RemoveItems(List<UUID> uuids)
390 {
391 lock (m_dbLock)
392 {
393 string sql = "delete from primitems where ";
394 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
395 {
396 dbcon.Open();
397
398 using (MySqlCommand cmd = dbcon.CreateCommand())
399 {
400 for (int i = 0; i < uuids.Count; i++)
401 {
402 if ((i + 1) == uuids.Count)
403 {
404 // end of the list
405 sql += "(PrimID = ?PrimID" + i + ")";
406 }
407 else
408 {
409 sql += "(PrimID = ?PrimID" + i + ") or ";
410 }
411 }
412 cmd.CommandText = sql;
413
414 for (int i = 0; i < uuids.Count; i++)
415 cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString());
416
417 ExecuteNonQuery(cmd);
418 }
419 dbcon.Close();
420 }
421 }
422 }
423
424 public virtual List<SceneObjectGroup> LoadObjects(UUID regionID)
425 {
426 const int ROWS_PER_QUERY = 5000;
427
428 Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(ROWS_PER_QUERY);
429 Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>();
430 int count = 0;
431
432 #region Prim Loading
433
434 lock (m_dbLock)
435 {
436 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
437 {
438 dbcon.Open();
439
440 using (MySqlCommand cmd = dbcon.CreateCommand())
441 {
442 cmd.CommandText =
443 "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID";
444 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
445 cmd.CommandTimeout = 3600;
446
447 using (IDataReader reader = ExecuteReader(cmd))
448 {
449 while (reader.Read())
450 {
451 SceneObjectPart prim = BuildPrim(reader);
452 if (reader["Shape"] is DBNull)
453 prim.Shape = PrimitiveBaseShape.Default;
454 else
455 prim.Shape = BuildShape(reader);
456
457 UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString());
458 if (parentID != prim.UUID)
459 prim.ParentUUID = parentID;
460
461 prims[prim.UUID] = prim;
462
463 ++count;
464 if (count % ROWS_PER_QUERY == 0)
465 m_log.Debug("[REGION DB]: Loaded " + count + " prims...");
466 }
467 }
468 }
469 dbcon.Close();
470 }
471 }
472
473 #endregion Prim Loading
474
475 #region SceneObjectGroup Creation
476
477 // Create all of the SOGs from the root prims first
478 foreach (SceneObjectPart prim in prims.Values)
479 {
480 if (prim.ParentUUID == UUID.Zero)
481 {
482 objects[prim.UUID] = new SceneObjectGroup(prim);
483 }
484 }
485
486 // Add all of the children objects to the SOGs
487 foreach (SceneObjectPart prim in prims.Values)
488 {
489 SceneObjectGroup sog;
490 if (prim.UUID != prim.ParentUUID)
491 {
492 if (objects.TryGetValue(prim.ParentUUID, out sog))
493 {
494 int originalLinkNum = prim.LinkNum;
495
496 sog.AddPart(prim);
497
498 // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum.
499 // We override that here
500 if (originalLinkNum != 0)
501 prim.LinkNum = originalLinkNum;
502 }
503 else
504 {
505 m_log.WarnFormat(
506 "[REGION DB]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.",
507 prim.Name, prim.UUID, regionID, prim.ParentUUID);
508 }
509 }
510 }
511
512 #endregion SceneObjectGroup Creation
513
514 m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count);
515
516 #region Prim Inventory Loading
517
518 // Instead of attempting to LoadItems on every prim,
519 // most of which probably have no items... get a
520 // list from DB of all prims which have items and
521 // LoadItems only on those
522 List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>();
523 lock (m_dbLock)
524 {
525 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
526 {
527 dbcon.Open();
528
529 using (MySqlCommand itemCmd = dbcon.CreateCommand())
530 {
531 itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems";
532 using (IDataReader itemReader = ExecuteReader(itemCmd))
533 {
534 while (itemReader.Read())
535 {
536 if (!(itemReader["primID"] is DBNull))
537 {
538 UUID primID = DBGuid.FromDB(itemReader["primID"].ToString());
539 if (prims.ContainsKey(primID))
540 primsWithInventory.Add(prims[primID]);
541 }
542 }
543 }
544 }
545 dbcon.Close();
546 }
547 }
548
549 foreach (SceneObjectPart prim in primsWithInventory)
550 {
551 LoadItems(prim);
552 }
553
554 #endregion Prim Inventory Loading
555
556 m_log.DebugFormat("[REGION DB]: Loaded inventory from {0} objects", primsWithInventory.Count);
557
558 return new List<SceneObjectGroup>(objects.Values);
559 }
560
561 /// <summary>
562 /// Load in a prim's persisted inventory.
563 /// </summary>
564 /// <param name="prim">The prim</param>
565 private void LoadItems(SceneObjectPart prim)
566 {
567 lock (m_dbLock)
568 {
569 List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
570
571 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
572 {
573 dbcon.Open();
574
575 using (MySqlCommand cmd = dbcon.CreateCommand())
576 {
577 cmd.CommandText = "select * from primitems where PrimID = ?PrimID";
578 cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString());
579
580 using (IDataReader reader = ExecuteReader(cmd))
581 {
582 while (reader.Read())
583 {
584 TaskInventoryItem item = BuildItem(reader);
585
586 item.ParentID = prim.UUID; // Values in database are often wrong
587 inventory.Add(item);
588 }
589 }
590 }
591 dbcon.Close();
592 }
593
594 prim.Inventory.RestoreInventoryItems(inventory);
595 }
596 }
597
598 // Legacy entry point for when terrain was always a 256x256 hieghtmap
599 public void StoreTerrain(double[,] ter, UUID regionID)
600 {
601 StoreTerrain(new HeightmapTerrainData(ter), regionID);
602 }
603
604 public void StoreTerrain(TerrainData terrData, UUID regionID)
605 {
606 Util.FireAndForget(delegate(object x)
607 {
608 m_log.Info("[REGION DB]: Storing terrain");
609
610 int terrainDBRevision;
611 Array terrainDBblob;
612 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
613
614 lock (m_dbLock)
615 {
616 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
617 {
618 dbcon.Open();
619
620 using (MySqlCommand cmd = dbcon.CreateCommand())
621 {
622 cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
623 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
624
625 using (MySqlCommand cmd2 = dbcon.CreateCommand())
626 {
627 try
628 {
629 cmd2.CommandText = "insert into terrain (RegionUUID, " +
630 "Revision, Heightfield) values (?RegionUUID, " +
631 "?Revision, ?Heightfield)";
632
633 cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
634 cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
635 cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
636
637 ExecuteNonQuery(cmd);
638 ExecuteNonQuery(cmd2);
639 }
640 catch (Exception e)
641 {
642 m_log.ErrorFormat(e.ToString());
643 }
644 }
645 }
646 dbcon.Close();
647 }
648 }
649 });
650 }
651
652 public void StoreBakedTerrain(TerrainData terrData, UUID regionID)
653 {
654 Util.FireAndForget(delegate(object x)
655 {
656 m_log.Info("[REGION DB]: Storing Baked terrain");
657
658 int terrainDBRevision;
659 Array terrainDBblob;
660 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
661
662 lock (m_dbLock)
663 {
664 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
665 {
666 dbcon.Open();
667
668 using (MySqlCommand cmd = dbcon.CreateCommand())
669 {
670 cmd.CommandText = "delete from bakedterrain where RegionUUID = ?RegionUUID";
671 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
672
673 using (MySqlCommand cmd2 = dbcon.CreateCommand())
674 {
675 try
676 {
677 cmd2.CommandText = "insert into bakedterrain (RegionUUID, " +
678 "Revision, Heightfield) values (?RegionUUID, " +
679 "?Revision, ?Heightfield)";
680
681 cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
682 cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
683 cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
684
685 ExecuteNonQuery(cmd);
686 ExecuteNonQuery(cmd2);
687 }
688 catch (Exception e)
689 {
690 m_log.ErrorFormat(e.ToString());
691 }
692 }
693 }
694 dbcon.Close();
695 }
696 }
697 });
698 }
699
700 // Legacy region loading
701 public virtual double[,] LoadTerrain(UUID regionID)
702 {
703 double[,] ret = null;
704 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
705 if (terrData != null)
706 ret = terrData.GetDoubles();
707 return ret;
708 }
709
710 // Returns 'null' if region not found
711 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
712 {
713 TerrainData terrData = null;
714 byte[] blob = null;
715 int rev = 0;
716
717 lock (m_dbLock)
718 {
719
720 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
721 {
722 dbcon.Open();
723
724 using (MySqlCommand cmd = dbcon.CreateCommand())
725 {
726 cmd.CommandText = "select RegionUUID, Revision, Heightfield " +
727 "from terrain where RegionUUID = ?RegionUUID " +
728 "order by Revision desc limit 1";
729 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
730
731 using (IDataReader reader = ExecuteReader(cmd))
732 {
733 while (reader.Read())
734 {
735 rev = Convert.ToInt32(reader["Revision"]);
736 if ((reader["Heightfield"] != DBNull.Value))
737 {
738 blob = (byte[])reader["Heightfield"];
739 }
740 }
741 }
742 }
743 dbcon.Close();
744 }
745 }
746
747 if(blob != null)
748 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
749
750 return terrData;
751 }
752
753 public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
754 {
755 TerrainData terrData = null;
756 byte[] blob = null;
757 int rev = 0;
758
759 lock (m_dbLock)
760 {
761 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
762 {
763 dbcon.Open();
764
765 using (MySqlCommand cmd = dbcon.CreateCommand())
766 {
767 cmd.CommandText = "select RegionUUID, Revision, Heightfield " +
768 "from bakedterrain where RegionUUID = ?RegionUUID ";
769 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
770
771 using (IDataReader reader = ExecuteReader(cmd))
772 {
773 while (reader.Read())
774 {
775 rev = Convert.ToInt32(reader["Revision"]);
776 if ((reader["Heightfield"] != DBNull.Value))
777 {
778 blob = (byte[])reader["Heightfield"];
779 }
780 }
781 }
782 }
783 dbcon.Close();
784 }
785 }
786 if(blob != null)
787 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
788
789 return terrData;
790 }
791
792 public virtual void RemoveLandObject(UUID globalID)
793 {
794 lock (m_dbLock)
795 {
796 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
797 {
798 dbcon.Open();
799
800 using (MySqlCommand cmd = dbcon.CreateCommand())
801 {
802 cmd.CommandText = "delete from land where UUID = ?UUID";
803 cmd.Parameters.AddWithValue("UUID", globalID.ToString());
804
805 ExecuteNonQuery(cmd);
806 }
807 dbcon.Close();
808 }
809 }
810 }
811
812 public virtual void StoreLandObject(ILandObject parcel)
813 {
814 lock (m_dbLock)
815 {
816 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
817 {
818 dbcon.Open();
819
820 using (MySqlCommand cmd = dbcon.CreateCommand())
821 {
822 cmd.CommandText = "replace into land (UUID, RegionUUID, " +
823 "LocalLandID, Bitmap, Name, Description, " +
824 "OwnerUUID, IsGroupOwned, Area, AuctionID, " +
825 "Category, ClaimDate, ClaimPrice, GroupUUID, " +
826 "SalePrice, LandStatus, LandFlags, LandingType, " +
827 "MediaAutoScale, MediaTextureUUID, MediaURL, " +
828 "MusicURL, PassHours, PassPrice, SnapshotUUID, " +
829 "UserLocationX, UserLocationY, UserLocationZ, " +
830 "UserLookAtX, UserLookAtY, UserLookAtZ, " +
831 "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
832 "MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " +
833 "SeeAVs, AnyAVSounds, GroupAVSounds) values (" +
834 "?UUID, ?RegionUUID, " +
835 "?LocalLandID, ?Bitmap, ?Name, ?Description, " +
836 "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
837 "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " +
838 "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " +
839 "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " +
840 "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " +
841 "?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
842 "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
843 "?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+
844 "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia, " +
845 "?SeeAVs, ?AnyAVSounds, ?GroupAVSounds)";
846
847 FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID);
848
849 ExecuteNonQuery(cmd);
850
851 cmd.CommandText = "delete from landaccesslist where LandUUID = ?UUID";
852
853 ExecuteNonQuery(cmd);
854
855 cmd.Parameters.Clear();
856 cmd.CommandText = "insert into landaccesslist (LandUUID, " +
857 "AccessUUID, Flags, Expires) values (?LandUUID, ?AccessUUID, " +
858 "?Flags, ?Expires)";
859
860 foreach (LandAccessEntry entry in parcel.LandData.ParcelAccessList)
861 {
862 FillLandAccessCommand(cmd, entry, parcel.LandData.GlobalID);
863 ExecuteNonQuery(cmd);
864 cmd.Parameters.Clear();
865 }
866 }
867 dbcon.Close();
868 }
869 }
870 }
871
872 public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
873 {
874 RegionLightShareData nWP = new RegionLightShareData();
875 nWP.OnSave += StoreRegionWindlightSettings;
876
877 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
878 {
879 dbcon.Open();
880
881 string command = "select * from `regionwindlight` where region_id = ?regionID";
882
883 using (MySqlCommand cmd = new MySqlCommand(command))
884 {
885 cmd.Connection = dbcon;
886
887 cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
888
889 using(IDataReader result = ExecuteReader(cmd))
890 {
891 if(!result.Read())
892 {
893 //No result, so store our default windlight profile and return it
894 nWP.regionID = regionUUID;
895 // StoreRegionWindlightSettings(nWP);
896 return nWP;
897 }
898 else
899 {
900 nWP.regionID = DBGuid.FromDB(result["region_id"]);
901 nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
902 nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
903 nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
904 nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
905 nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
906 nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
907 nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
908 nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
909 nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
910 nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
911 nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
912 nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
913 nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
914 nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
915 nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
916 nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
917 nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
918 UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture);
919 nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
920 nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
921 nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
922 nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
923 nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
924 nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
925 nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
926 nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
927 nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
928 nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
929 nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
930 nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
931 nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
932 nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
933 nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
934 nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
935 nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
936 nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
937 nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
938 nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
939 nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
940 nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
941 nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
942 nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
943 nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
944 nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
945 nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
946 nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
947 nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
948 nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
949 nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
950 nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
951 nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
952 nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
953 nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
954 nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
955 nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
956 nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
957 nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
958 nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
959 nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
960 nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
961 nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
962 nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
963 nWP.valid = true;
964 }
965 }
966 }
967 dbcon.Close();
968 }
969
970 return nWP;
971 }
972
973 public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
974 {
975 RegionSettings rs = null;
976 bool needStore = false;
977
978 lock (m_dbLock)
979 {
980 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
981 {
982 dbcon.Open();
983
984 using (MySqlCommand cmd = dbcon.CreateCommand())
985 {
986 cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID";
987 cmd.Parameters.AddWithValue("regionUUID", regionUUID);
988
989 using (IDataReader reader = ExecuteReader(cmd))
990 {
991 if (reader.Read())
992 {
993 rs = BuildRegionSettings(reader);
994 rs.OnSave += StoreRegionSettings;
995 }
996 else
997 {
998 rs = new RegionSettings();
999 rs.RegionUUID = regionUUID;
1000 rs.OnSave += StoreRegionSettings;
1001
1002 needStore = true;
1003 }
1004 }
1005 }
1006 dbcon.Close();
1007 }
1008 }
1009
1010 if(needStore)
1011 StoreRegionSettings(rs);
1012
1013 LoadSpawnPoints(rs);
1014
1015 return rs;
1016 }
1017
1018 public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
1019 {
1020 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1021 {
1022 dbcon.Open();
1023
1024 using (MySqlCommand cmd = dbcon.CreateCommand())
1025 {
1026 cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "
1027 + "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "
1028 + "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "
1029 + "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "
1030 + "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "
1031 + "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "
1032 + "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "
1033 + "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "
1034 + "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "
1035 + "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "
1036 + "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "
1037 + "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "
1038 + "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "
1039 + "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "
1040 + "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "
1041 + "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "
1042 + "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "
1043 + "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "
1044 + "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "
1045 + "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "
1046 + "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "
1047 + "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "
1048 + "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "
1049 + "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "
1050 + "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"
1051 ;
1052
1053 cmd.Parameters.AddWithValue("region_id", wl.regionID);
1054 cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
1055 cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
1056 cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
1057 cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
1058 cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
1059 cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
1060 cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
1061 cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
1062 cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
1063 cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
1064 cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
1065 cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
1066 cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
1067 cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
1068 cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
1069 cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
1070 cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
1071 cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
1072 cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
1073 cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
1074 cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
1075 cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
1076 cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
1077 cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
1078 cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
1079 cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
1080 cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
1081 cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
1082 cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
1083 cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
1084 cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
1085 cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
1086 cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
1087 cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
1088 cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
1089 cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
1090 cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
1091 cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
1092 cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
1093 cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
1094 cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
1095 cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
1096 cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
1097 cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
1098 cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
1099 cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
1100 cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
1101 cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
1102 cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
1103 cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
1104 cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
1105 cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
1106 cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
1107 cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
1108 cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
1109 cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
1110 cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
1111 cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
1112 cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
1113 cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
1114 cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
1115 cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
1116
1117 ExecuteNonQuery(cmd);
1118 }
1119 dbcon.Close();
1120 }
1121 }
1122
1123 public virtual void RemoveRegionWindlightSettings(UUID regionID)
1124 {
1125 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1126 {
1127 dbcon.Open();
1128
1129 using (MySqlCommand cmd = dbcon.CreateCommand())
1130 {
1131 cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
1132 cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
1133 ExecuteNonQuery(cmd);
1134 }
1135 dbcon.Close();
1136 }
1137 }
1138
1139 #region RegionEnvironmentSettings
1140 public string LoadRegionEnvironmentSettings(UUID regionUUID)
1141 {
1142 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1143 {
1144 dbcon.Open();
1145
1146 string command = "select * from `regionenvironment` where region_id = ?region_id";
1147
1148 using (MySqlCommand cmd = new MySqlCommand(command))
1149 {
1150 cmd.Connection = dbcon;
1151
1152 cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
1153
1154 using(IDataReader result = ExecuteReader(cmd))
1155 {
1156 if(!result.Read())
1157 {
1158 dbcon.Close();
1159 return String.Empty;
1160 }
1161 else
1162 {
1163 string ret = Convert.ToString(result["llsd_settings"]);
1164 dbcon.Close();
1165 return ret;
1166 }
1167 }
1168 }
1169 }
1170 }
1171
1172 public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
1173 {
1174 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1175 {
1176 dbcon.Open();
1177
1178 using (MySqlCommand cmd = dbcon.CreateCommand())
1179 {
1180 cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
1181
1182 cmd.Parameters.AddWithValue("region_id", regionUUID);
1183 cmd.Parameters.AddWithValue("llsd_settings", settings);
1184
1185 ExecuteNonQuery(cmd);
1186 }
1187 dbcon.Close();
1188 }
1189 }
1190
1191 public void RemoveRegionEnvironmentSettings(UUID regionUUID)
1192 {
1193 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1194 {
1195 dbcon.Open();
1196
1197 using (MySqlCommand cmd = dbcon.CreateCommand())
1198 {
1199 cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
1200 cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
1201 ExecuteNonQuery(cmd);
1202 }
1203 dbcon.Close();
1204 }
1205 }
1206 #endregion
1207
1208 public virtual void StoreRegionSettings(RegionSettings rs)
1209 {
1210 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1211 {
1212 dbcon.Open();
1213
1214 using (MySqlCommand cmd = dbcon.CreateCommand())
1215 {
1216 cmd.CommandText = "replace into regionsettings (regionUUID, " +
1217 "block_terraform, block_fly, allow_damage, " +
1218 "restrict_pushing, allow_land_resell, " +
1219 "allow_land_join_divide, block_show_in_search, " +
1220 "agent_limit, object_bonus, maturity, " +
1221 "disable_scripts, disable_collisions, " +
1222 "disable_physics, terrain_texture_1, " +
1223 "terrain_texture_2, terrain_texture_3, " +
1224 "terrain_texture_4, elevation_1_nw, " +
1225 "elevation_2_nw, elevation_1_ne, " +
1226 "elevation_2_ne, elevation_1_se, " +
1227 "elevation_2_se, elevation_1_sw, " +
1228 "elevation_2_sw, water_height, " +
1229 "terrain_raise_limit, terrain_lower_limit, " +
1230 "use_estate_sun, fixed_sun, sun_position, " +
1231 "covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
1232 "sunvectorz, loaded_creation_datetime, " +
1233 "loaded_creation_id, map_tile_ID, block_search, casino, " +
1234 "TelehubObject, parcel_tile_ID) " +
1235 "values (?RegionUUID, ?BlockTerraform, " +
1236 "?BlockFly, ?AllowDamage, ?RestrictPushing, " +
1237 "?AllowLandResell, ?AllowLandJoinDivide, " +
1238 "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
1239 "?Maturity, ?DisableScripts, ?DisableCollisions, " +
1240 "?DisablePhysics, ?TerrainTexture1, " +
1241 "?TerrainTexture2, ?TerrainTexture3, " +
1242 "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
1243 "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
1244 "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
1245 "?WaterHeight, ?TerrainRaiseLimit, " +
1246 "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
1247 "?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
1248 "?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
1249 "?LoadedCreationDateTime, ?LoadedCreationID, " +
1250 "?TerrainImageID, ?block_search, ?casino, " +
1251 "?TelehubObject, ?ParcelImageID)";
1252
1253 FillRegionSettingsCommand(cmd, rs);
1254 ExecuteNonQuery(cmd);
1255 }
1256 dbcon.Close();
1257 SaveSpawnPoints(rs);
1258 }
1259 }
1260
1261 public virtual List<LandData> LoadLandObjects(UUID regionUUID)
1262 {
1263 List<LandData> landData = new List<LandData>();
1264
1265 lock (m_dbLock)
1266 {
1267 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1268 {
1269 dbcon.Open();
1270
1271 using (MySqlCommand cmd = dbcon.CreateCommand())
1272 {
1273 cmd.CommandText = "select * from land where RegionUUID = ?RegionUUID";
1274 cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString());
1275
1276 using (IDataReader reader = ExecuteReader(cmd))
1277 {
1278 while (reader.Read())
1279 {
1280 LandData newLand = BuildLandData(reader);
1281 landData.Add(newLand);
1282 }
1283 }
1284 }
1285
1286 using (MySqlCommand cmd = dbcon.CreateCommand())
1287 {
1288 foreach (LandData land in landData)
1289 {
1290 cmd.Parameters.Clear();
1291 cmd.CommandText = "select * from landaccesslist where LandUUID = ?LandUUID";
1292 cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString());
1293
1294 using (IDataReader reader = ExecuteReader(cmd))
1295 {
1296 while (reader.Read())
1297 {
1298 land.ParcelAccessList.Add(BuildLandAccessData(reader));
1299 }
1300 }
1301 }
1302 }
1303 dbcon.Close();
1304 }
1305 }
1306
1307 return landData;
1308 }
1309
1310 public void Shutdown()
1311 {
1312 }
1313
1314 private SceneObjectPart BuildPrim(IDataReader row)
1315 {
1316 SceneObjectPart prim = new SceneObjectPart();
1317
1318 // depending on the MySQL connector version, CHAR(36) may be already converted to Guid!
1319 prim.UUID = DBGuid.FromDB(row["UUID"]);
1320 prim.CreatorIdentification = (string)row["CreatorID"];
1321 prim.OwnerID = DBGuid.FromDB(row["OwnerID"]);
1322 prim.GroupID = DBGuid.FromDB(row["GroupID"]);
1323 prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]);
1324 if (row["RezzerID"] != DBNull.Value)
1325 prim.RezzerID = DBGuid.FromDB(row["RezzerID"]);
1326 else
1327 prim.RezzerID = UUID.Zero;
1328
1329 // explicit conversion of integers is required, which sort
1330 // of sucks. No idea if there is a shortcut here or not.
1331 prim.CreationDate = (int)row["CreationDate"];
1332 if (row["Name"] != DBNull.Value)
1333 prim.Name = (string)row["Name"];
1334 else
1335 prim.Name = String.Empty;
1336 // Various text fields
1337 prim.Text = (string)row["Text"];
1338 prim.Color = Color.FromArgb((int)row["ColorA"],
1339 (int)row["ColorR"],
1340 (int)row["ColorG"],
1341 (int)row["ColorB"]);
1342 prim.Description = (string)row["Description"];
1343 prim.SitName = (string)row["SitName"];
1344 prim.TouchName = (string)row["TouchName"];
1345 // Permissions
1346 prim.Flags = (PrimFlags)(int)row["ObjectFlags"];
1347 prim.OwnerMask = (uint)(int)row["OwnerMask"];
1348 prim.NextOwnerMask = (uint)(int)row["NextOwnerMask"];
1349 prim.GroupMask = (uint)(int)row["GroupMask"];
1350 prim.EveryoneMask = (uint)(int)row["EveryoneMask"];
1351 prim.BaseMask = (uint)(int)row["BaseMask"];
1352
1353 // Vectors
1354 prim.OffsetPosition = new Vector3(
1355 (float)(double)row["PositionX"],
1356 (float)(double)row["PositionY"],
1357 (float)(double)row["PositionZ"]
1358 );
1359 prim.GroupPosition = new Vector3(
1360 (float)(double)row["GroupPositionX"],
1361 (float)(double)row["GroupPositionY"],
1362 (float)(double)row["GroupPositionZ"]
1363 );
1364 prim.Velocity = new Vector3(
1365 (float)(double)row["VelocityX"],
1366 (float)(double)row["VelocityY"],
1367 (float)(double)row["VelocityZ"]
1368 );
1369 prim.AngularVelocity = new Vector3(
1370 (float)(double)row["AngularVelocityX"],
1371 (float)(double)row["AngularVelocityY"],
1372 (float)(double)row["AngularVelocityZ"]
1373 );
1374 prim.Acceleration = new Vector3(
1375 (float)(double)row["AccelerationX"],
1376 (float)(double)row["AccelerationY"],
1377 (float)(double)row["AccelerationZ"]
1378 );
1379 // quaternions
1380 prim.RotationOffset = new Quaternion(
1381 (float)(double)row["RotationX"],
1382 (float)(double)row["RotationY"],
1383 (float)(double)row["RotationZ"],
1384 (float)(double)row["RotationW"]
1385 );
1386 prim.SitTargetPositionLL = new Vector3(
1387 (float)(double)row["SitTargetOffsetX"],
1388 (float)(double)row["SitTargetOffsetY"],
1389 (float)(double)row["SitTargetOffsetZ"]
1390 );
1391 prim.SitTargetOrientationLL = new Quaternion(
1392 (float)(double)row["SitTargetOrientX"],
1393 (float)(double)row["SitTargetOrientY"],
1394 (float)(double)row["SitTargetOrientZ"],
1395 (float)(double)row["SitTargetOrientW"]
1396 );
1397
1398 prim.PayPrice[0] = (int)row["PayPrice"];
1399 prim.PayPrice[1] = (int)row["PayButton1"];
1400 prim.PayPrice[2] = (int)row["PayButton2"];
1401 prim.PayPrice[3] = (int)row["PayButton3"];
1402 prim.PayPrice[4] = (int)row["PayButton4"];
1403
1404 prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString());
1405 prim.SoundGain = (float)(double)row["LoopedSoundGain"];
1406 prim.SoundFlags = 1; // If it's persisted at all, it's looped
1407
1408 if (!(row["TextureAnimation"] is DBNull))
1409 prim.TextureAnimation = (byte[])row["TextureAnimation"];
1410 if (!(row["ParticleSystem"] is DBNull))
1411 prim.ParticleSystem = (byte[])row["ParticleSystem"];
1412
1413 prim.AngularVelocity = new Vector3(
1414 (float)(double)row["OmegaX"],
1415 (float)(double)row["OmegaY"],
1416 (float)(double)row["OmegaZ"]
1417 );
1418
1419 prim.SetCameraEyeOffset(new Vector3(
1420 (float)(double)row["CameraEyeOffsetX"],
1421 (float)(double)row["CameraEyeOffsetY"],
1422 (float)(double)row["CameraEyeOffsetZ"]
1423 ));
1424
1425 prim.SetCameraAtOffset(new Vector3(
1426 (float)(double)row["CameraAtOffsetX"],
1427 (float)(double)row["CameraAtOffsetY"],
1428 (float)(double)row["CameraAtOffsetZ"]
1429 ));
1430
1431 prim.SetForceMouselook((sbyte)row["ForceMouselook"] != 0);
1432 prim.ScriptAccessPin = (int)row["ScriptAccessPin"];
1433 prim.AllowedDrop = ((sbyte)row["AllowedDrop"] != 0);
1434 prim.DIE_AT_EDGE = ((sbyte)row["DieAtEdge"] != 0);
1435
1436 prim.SalePrice = (int)row["SalePrice"];
1437 prim.ObjectSaleType = unchecked((byte)(sbyte)row["SaleType"]);
1438
1439 prim.Material = unchecked((byte)(sbyte)row["Material"]);
1440
1441 if (!(row["ClickAction"] is DBNull))
1442 prim.ClickAction = unchecked((byte)(sbyte)row["ClickAction"]);
1443
1444 prim.CollisionSound = DBGuid.FromDB(row["CollisionSound"]);
1445 prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"];
1446
1447 prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
1448 prim.PassCollisions = ((sbyte)row["PassCollisions"] != 0);
1449 prim.LinkNum = (int)row["LinkNumber"];
1450
1451 if (!(row["MediaURL"] is System.DBNull))
1452 prim.MediaUrl = (string)row["MediaURL"];
1453
1454 if (!(row["AttachedPosX"] is System.DBNull))
1455 {
1456 prim.AttachedPos = new Vector3(
1457 (float)(double)row["AttachedPosX"],
1458 (float)(double)row["AttachedPosY"],
1459 (float)(double)row["AttachedPosZ"]
1460 );
1461 }
1462
1463 if (!(row["DynAttrs"] is System.DBNull))
1464 prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]);
1465 else
1466 prim.DynAttrs = new DAMap();
1467
1468 if (!(row["KeyframeMotion"] is DBNull))
1469 {
1470 Byte[] data = (byte[])row["KeyframeMotion"];
1471 if (data.Length > 0)
1472 prim.KeyframeMotion = KeyframeMotion.FromData(null, data);
1473 else
1474 prim.KeyframeMotion = null;
1475 }
1476 else
1477 {
1478 prim.KeyframeMotion = null;
1479 }
1480
1481 prim.PhysicsShapeType = (byte)Convert.ToInt32(row["PhysicsShapeType"].ToString());
1482 prim.Density = (float)(double)row["Density"];
1483 prim.GravityModifier = (float)(double)row["GravityModifier"];
1484 prim.Friction = (float)(double)row["Friction"];
1485 prim.Restitution = (float)(double)row["Restitution"];
1486 prim.RotationAxisLocks = (byte)Convert.ToInt32(row["RotationAxisLocks"].ToString());
1487
1488 SOPVehicle vehicle = null;
1489
1490 if (row["Vehicle"].ToString() != String.Empty)
1491 {
1492 vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString());
1493 if (vehicle != null)
1494 prim.VehicleParams = vehicle;
1495 }
1496
1497 PhysicsInertiaData pdata = null;
1498 if (row["PhysInertia"].ToString() != String.Empty)
1499 pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString());
1500 prim.PhysicsInertia = pdata;
1501
1502 return prim;
1503 }
1504
1505 /// <summary>
1506 /// Build a prim inventory item from the persisted data.
1507 /// </summary>
1508 /// <param name="row"></param>
1509 /// <returns></returns>
1510 private static TaskInventoryItem BuildItem(IDataReader row)
1511 {
1512 try
1513 {
1514 TaskInventoryItem taskItem = new TaskInventoryItem();
1515
1516 taskItem.ItemID = DBGuid.FromDB(row["itemID"]);
1517 taskItem.ParentPartID = DBGuid.FromDB(row["primID"]);
1518 taskItem.AssetID = DBGuid.FromDB(row["assetID"]);
1519 taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]);
1520
1521 taskItem.InvType = Convert.ToInt32(row["invType"]);
1522 taskItem.Type = Convert.ToInt32(row["assetType"]);
1523
1524 taskItem.Name = (String)row["name"];
1525 taskItem.Description = (String)row["description"];
1526 taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
1527 taskItem.CreatorIdentification = (String)row["creatorID"];
1528 taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]);
1529 taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]);
1530 taskItem.GroupID = DBGuid.FromDB(row["groupID"]);
1531
1532 taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
1533 taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
1534 taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
1535 taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
1536 taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
1537 taskItem.Flags = Convert.ToUInt32(row["flags"]);
1538
1539 return taskItem;
1540 }
1541 catch
1542 {
1543 m_log.ErrorFormat("[MYSQL DB]: Error reading task inventory: itemID was {0}, primID was {1}", row["itemID"].ToString(), row["primID"].ToString());
1544 throw;
1545 }
1546 }
1547
1548 private static RegionSettings BuildRegionSettings(IDataReader row)
1549 {
1550 RegionSettings newSettings = new RegionSettings();
1551
1552 newSettings.RegionUUID = DBGuid.FromDB(row["regionUUID"]);
1553 newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]);
1554 newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]);
1555 newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]);
1556 newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]);
1557 newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]);
1558 newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]);
1559 newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]);
1560 newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]);
1561 newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]);
1562 newSettings.Maturity = Convert.ToInt32(row["maturity"]);
1563 newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]);
1564 newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]);
1565 newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]);
1566 newSettings.TerrainTexture1 = DBGuid.FromDB(row["terrain_texture_1"]);
1567 newSettings.TerrainTexture2 = DBGuid.FromDB(row["terrain_texture_2"]);
1568 newSettings.TerrainTexture3 = DBGuid.FromDB(row["terrain_texture_3"]);
1569 newSettings.TerrainTexture4 = DBGuid.FromDB(row["terrain_texture_4"]);
1570 newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]);
1571 newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]);
1572 newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]);
1573 newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]);
1574 newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]);
1575 newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]);
1576 newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]);
1577 newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]);
1578 newSettings.WaterHeight = Convert.ToDouble(row["water_height"]);
1579 newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
1580 newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
1581 newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
1582 newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]);
1583 newSettings.SunVector = new Vector3 (
1584 Convert.ToSingle(row["sunvectorx"]),
1585 Convert.ToSingle(row["sunvectory"]),
1586 Convert.ToSingle(row["sunvectorz"])
1587 );
1588 newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
1589 newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
1590 newSettings.Covenant = DBGuid.FromDB(row["covenant"]);
1591 newSettings.CovenantChangedDateTime = Convert.ToInt32(row["covenant_datetime"]);
1592 newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]);
1593
1594 if (row["loaded_creation_id"] is DBNull)
1595 newSettings.LoadedCreationID = "";
1596 else
1597 newSettings.LoadedCreationID = (String) row["loaded_creation_id"];
1598
1599 newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]);
1600 newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]);
1601 newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]);
1602
1603 newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
1604 newSettings.Casino = Convert.ToBoolean(row["casino"]);
1605
1606 return newSettings;
1607 }
1608
1609 /// <summary>
1610 ///
1611 /// </summary>
1612 /// <param name="row"></param>
1613 /// <returns></returns>
1614 private static LandData BuildLandData(IDataReader row)
1615 {
1616 LandData newData = new LandData();
1617
1618 newData.GlobalID = DBGuid.FromDB(row["UUID"]);
1619 newData.LocalID = Convert.ToInt32(row["LocalLandID"]);
1620
1621 // Bitmap is a byte[512]
1622 newData.Bitmap = (Byte[]) row["Bitmap"];
1623
1624 newData.Name = (String) row["Name"];
1625 newData.Description = (String) row["Description"];
1626 newData.OwnerID = DBGuid.FromDB(row["OwnerUUID"]);
1627 newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]);
1628 newData.Area = Convert.ToInt32(row["Area"]);
1629 newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented
1630 newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]);
1631 //Enum libsecondlife.Parcel.ParcelCategory
1632 newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]);
1633 newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]);
1634 newData.GroupID = DBGuid.FromDB(row["GroupUUID"]);
1635 newData.SalePrice = Convert.ToInt32(row["SalePrice"]);
1636 newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]);
1637 //Enum. libsecondlife.Parcel.ParcelStatus
1638 newData.Flags = Convert.ToUInt32(row["LandFlags"]);
1639 newData.LandingType = Convert.ToByte(row["LandingType"]);
1640 newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]);
1641 newData.MediaID = DBGuid.FromDB(row["MediaTextureUUID"]);
1642 newData.MediaURL = (String) row["MediaURL"];
1643 newData.MusicURL = (String) row["MusicURL"];
1644 newData.PassHours = Convert.ToSingle(row["PassHours"]);
1645 newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
1646 UUID authedbuyer = UUID.Zero;
1647 UUID snapshotID = UUID.Zero;
1648
1649 UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer);
1650 UUID.TryParse((string)row["SnapshotUUID"], out snapshotID);
1651 newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
1652 newData.Dwell = Convert.ToSingle(row["Dwell"]);
1653
1654 newData.AuthBuyerID = authedbuyer;
1655 newData.SnapshotID = snapshotID;
1656 try
1657 {
1658 newData.UserLocation =
1659 new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]),
1660 Convert.ToSingle(row["UserLocationZ"]));
1661 newData.UserLookAt =
1662 new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]),
1663 Convert.ToSingle(row["UserLookAtZ"]));
1664 }
1665 catch (InvalidCastException)
1666 {
1667 newData.UserLocation = Vector3.Zero;
1668 newData.UserLookAt = Vector3.Zero;
1669 m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name);
1670 }
1671
1672 newData.MediaDescription = (string) row["MediaDescription"];
1673 newData.MediaType = (string) row["MediaType"];
1674 newData.MediaWidth = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[0]);
1675 newData.MediaHeight = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[1]);
1676 newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
1677 newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
1678 newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
1679
1680 newData.ParcelAccessList = new List<LandAccessEntry>();
1681
1682 if (!(row["SeeAVs"] is System.DBNull))
1683 newData.SeeAVs = Convert.ToInt32(row["SeeAVs"]) != 0 ? true : false;
1684 if (!(row["AnyAVSounds"] is System.DBNull))
1685 newData.AnyAVSounds = Convert.ToInt32(row["AnyAVSounds"]) != 0 ? true : false;
1686 if (!(row["GroupAVSounds"] is System.DBNull))
1687 newData.GroupAVSounds = Convert.ToInt32(row["GroupAVSounds"]) != 0 ? true : false;
1688
1689 return newData;
1690 }
1691
1692 /// <summary>
1693 ///
1694 /// </summary>
1695 /// <param name="row"></param>
1696 /// <returns></returns>
1697 private static LandAccessEntry BuildLandAccessData(IDataReader row)
1698 {
1699 LandAccessEntry entry = new LandAccessEntry();
1700 entry.AgentID = DBGuid.FromDB(row["AccessUUID"]);
1701 entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]);
1702 entry.Expires = Convert.ToInt32(row["Expires"]);
1703 return entry;
1704 }
1705
1706 /// <summary>
1707 /// Fill the prim command with prim values
1708 /// </summary>
1709 /// <param name="row"></param>
1710 /// <param name="prim"></param>
1711 /// <param name="sceneGroupID"></param>
1712 /// <param name="regionUUID"></param>
1713 private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
1714 {
1715 cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString());
1716 cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString());
1717 cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate);
1718 cmd.Parameters.AddWithValue("Name", prim.Name);
1719 cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString());
1720 // the UUID of the root part for this SceneObjectGroup
1721 // various text fields
1722 cmd.Parameters.AddWithValue("Text", prim.Text);
1723 cmd.Parameters.AddWithValue("ColorR", prim.Color.R);
1724 cmd.Parameters.AddWithValue("ColorG", prim.Color.G);
1725 cmd.Parameters.AddWithValue("ColorB", prim.Color.B);
1726 cmd.Parameters.AddWithValue("ColorA", prim.Color.A);
1727 cmd.Parameters.AddWithValue("Description", prim.Description);
1728 cmd.Parameters.AddWithValue("SitName", prim.SitName);
1729 cmd.Parameters.AddWithValue("TouchName", prim.TouchName);
1730 // permissions
1731 cmd.Parameters.AddWithValue("ObjectFlags", (uint)prim.Flags);
1732 cmd.Parameters.AddWithValue("CreatorID", prim.CreatorIdentification.ToString());
1733 cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString());
1734 cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString());
1735 cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString());
1736 cmd.Parameters.AddWithValue("RezzerID", prim.RezzerID.ToString());
1737 cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask);
1738 cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask);
1739 cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask);
1740 cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask);
1741 cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask);
1742 // vectors
1743 cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X);
1744 cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y);
1745 cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z);
1746 cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X);
1747 cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y);
1748 cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z);
1749 cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X);
1750 cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y);
1751 cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z);
1752 cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X);
1753 cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y);
1754 cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z);
1755 cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X);
1756 cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y);
1757 cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z);
1758 // quaternions
1759 cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X);
1760 cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y);
1761 cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z);
1762 cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W);
1763
1764 // Sit target
1765 Vector3 sitTargetPos = prim.SitTargetPositionLL;
1766 cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X);
1767 cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y);
1768 cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z);
1769
1770 Quaternion sitTargetOrient = prim.SitTargetOrientationLL;
1771 cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W);
1772 cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X);
1773 cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y);
1774 cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z);
1775
1776 cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]);
1777 cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]);
1778 cmd.Parameters.AddWithValue("PayButton2", prim.PayPrice[2]);
1779 cmd.Parameters.AddWithValue("PayButton3", prim.PayPrice[3]);
1780 cmd.Parameters.AddWithValue("PayButton4", prim.PayPrice[4]);
1781
1782 if ((prim.SoundFlags & 1) != 0) // Looped
1783 {
1784 cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString());
1785 cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain);
1786 }
1787 else
1788 {
1789 cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero);
1790 cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f);
1791 }
1792
1793 cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation);
1794 cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem);
1795
1796 cmd.Parameters.AddWithValue("OmegaX", (double)prim.AngularVelocity.X);
1797 cmd.Parameters.AddWithValue("OmegaY", (double)prim.AngularVelocity.Y);
1798 cmd.Parameters.AddWithValue("OmegaZ", (double)prim.AngularVelocity.Z);
1799
1800 cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X);
1801 cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y);
1802 cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z);
1803
1804 cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X);
1805 cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y);
1806 cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z);
1807
1808 if (prim.GetForceMouselook())
1809 cmd.Parameters.AddWithValue("ForceMouselook", 1);
1810 else
1811 cmd.Parameters.AddWithValue("ForceMouselook", 0);
1812
1813 cmd.Parameters.AddWithValue("ScriptAccessPin", prim.ScriptAccessPin);
1814
1815 if (prim.AllowedDrop)
1816 cmd.Parameters.AddWithValue("AllowedDrop", 1);
1817 else
1818 cmd.Parameters.AddWithValue("AllowedDrop", 0);
1819
1820 if (prim.DIE_AT_EDGE)
1821 cmd.Parameters.AddWithValue("DieAtEdge", 1);
1822 else
1823 cmd.Parameters.AddWithValue("DieAtEdge", 0);
1824
1825 cmd.Parameters.AddWithValue("SalePrice", prim.SalePrice);
1826 cmd.Parameters.AddWithValue("SaleType", unchecked((sbyte)(prim.ObjectSaleType)));
1827
1828 byte clickAction = prim.ClickAction;
1829 cmd.Parameters.AddWithValue("ClickAction", unchecked((sbyte)(clickAction)));
1830
1831 cmd.Parameters.AddWithValue("Material", unchecked((sbyte)(prim.Material)));
1832
1833 cmd.Parameters.AddWithValue("CollisionSound", prim.CollisionSound.ToString());
1834 cmd.Parameters.AddWithValue("CollisionSoundVolume", prim.CollisionSoundVolume);
1835
1836 if (prim.PassTouches)
1837 cmd.Parameters.AddWithValue("PassTouches", 1);
1838 else
1839 cmd.Parameters.AddWithValue("PassTouches", 0);
1840
1841 if (prim.PassCollisions)
1842 cmd.Parameters.AddWithValue("PassCollisions", 1);
1843 else
1844 cmd.Parameters.AddWithValue("PassCollisions", 0);
1845
1846 cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
1847 cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
1848 if (prim.AttachedPos != null)
1849 {
1850 cmd.Parameters.AddWithValue("AttachedPosX", (double)prim.AttachedPos.X);
1851 cmd.Parameters.AddWithValue("AttachedPosY", (double)prim.AttachedPos.Y);
1852 cmd.Parameters.AddWithValue("AttachedPosZ", (double)prim.AttachedPos.Z);
1853 }
1854
1855 if (prim.KeyframeMotion != null)
1856 cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize());
1857 else
1858 cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
1859
1860 if (prim.PhysicsInertia != null)
1861 cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2());
1862 else
1863 cmd.Parameters.AddWithValue("PhysInertia", String.Empty);
1864
1865 if (prim.VehicleParams != null)
1866 cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());
1867 else
1868 cmd.Parameters.AddWithValue("Vehicle", String.Empty);
1869
1870 if (prim.DynAttrs.CountNamespaces > 0)
1871 cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
1872 else
1873 cmd.Parameters.AddWithValue("DynAttrs", null);
1874
1875 cmd.Parameters.AddWithValue("PhysicsShapeType", prim.PhysicsShapeType);
1876 cmd.Parameters.AddWithValue("Density", (double)prim.Density);
1877 cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier);
1878 cmd.Parameters.AddWithValue("Friction", (double)prim.Friction);
1879 cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution);
1880 cmd.Parameters.AddWithValue("RotationAxisLocks", prim.RotationAxisLocks);
1881 }
1882
1883 /// <summary>
1884 ///
1885 /// </summary>
1886 /// <param name="row"></param>
1887 /// <param name="taskItem"></param>
1888 private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem)
1889 {
1890 cmd.Parameters.AddWithValue("itemID", taskItem.ItemID);
1891 cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID);
1892 cmd.Parameters.AddWithValue("assetID", taskItem.AssetID);
1893 cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID);
1894
1895 cmd.Parameters.AddWithValue("invType", taskItem.InvType);
1896 cmd.Parameters.AddWithValue("assetType", taskItem.Type);
1897
1898 cmd.Parameters.AddWithValue("name", taskItem.Name);
1899 cmd.Parameters.AddWithValue("description", taskItem.Description);
1900 cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate);
1901 cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorIdentification);
1902 cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID);
1903 cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID);
1904 cmd.Parameters.AddWithValue("groupID", taskItem.GroupID);
1905 cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions);
1906 cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions);
1907 cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions);
1908 cmd.Parameters.AddWithValue("everyonePermissions", taskItem.EveryonePermissions);
1909 cmd.Parameters.AddWithValue("groupPermissions", taskItem.GroupPermissions);
1910 cmd.Parameters.AddWithValue("flags", taskItem.Flags);
1911 }
1912
1913 /// <summary>
1914 ///
1915 /// </summary>
1916 private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings settings)
1917 {
1918 cmd.Parameters.AddWithValue("RegionUUID", settings.RegionUUID.ToString());
1919 cmd.Parameters.AddWithValue("BlockTerraform", settings.BlockTerraform);
1920 cmd.Parameters.AddWithValue("BlockFly", settings.BlockFly);
1921 cmd.Parameters.AddWithValue("AllowDamage", settings.AllowDamage);
1922 cmd.Parameters.AddWithValue("RestrictPushing", settings.RestrictPushing);
1923 cmd.Parameters.AddWithValue("AllowLandResell", settings.AllowLandResell);
1924 cmd.Parameters.AddWithValue("AllowLandJoinDivide", settings.AllowLandJoinDivide);
1925 cmd.Parameters.AddWithValue("BlockShowInSearch", settings.BlockShowInSearch);
1926 cmd.Parameters.AddWithValue("AgentLimit", settings.AgentLimit);
1927 cmd.Parameters.AddWithValue("ObjectBonus", settings.ObjectBonus);
1928 cmd.Parameters.AddWithValue("Maturity", settings.Maturity);
1929 cmd.Parameters.AddWithValue("DisableScripts", settings.DisableScripts);
1930 cmd.Parameters.AddWithValue("DisableCollisions", settings.DisableCollisions);
1931 cmd.Parameters.AddWithValue("DisablePhysics", settings.DisablePhysics);
1932 cmd.Parameters.AddWithValue("TerrainTexture1", settings.TerrainTexture1.ToString());
1933 cmd.Parameters.AddWithValue("TerrainTexture2", settings.TerrainTexture2.ToString());
1934 cmd.Parameters.AddWithValue("TerrainTexture3", settings.TerrainTexture3.ToString());
1935 cmd.Parameters.AddWithValue("TerrainTexture4", settings.TerrainTexture4.ToString());
1936 cmd.Parameters.AddWithValue("Elevation1NW", settings.Elevation1NW);
1937 cmd.Parameters.AddWithValue("Elevation2NW", settings.Elevation2NW);
1938 cmd.Parameters.AddWithValue("Elevation1NE", settings.Elevation1NE);
1939 cmd.Parameters.AddWithValue("Elevation2NE", settings.Elevation2NE);
1940 cmd.Parameters.AddWithValue("Elevation1SE", settings.Elevation1SE);
1941 cmd.Parameters.AddWithValue("Elevation2SE", settings.Elevation2SE);
1942 cmd.Parameters.AddWithValue("Elevation1SW", settings.Elevation1SW);
1943 cmd.Parameters.AddWithValue("Elevation2SW", settings.Elevation2SW);
1944 cmd.Parameters.AddWithValue("WaterHeight", settings.WaterHeight);
1945 cmd.Parameters.AddWithValue("TerrainRaiseLimit", settings.TerrainRaiseLimit);
1946 cmd.Parameters.AddWithValue("TerrainLowerLimit", settings.TerrainLowerLimit);
1947 cmd.Parameters.AddWithValue("UseEstateSun", settings.UseEstateSun);
1948 cmd.Parameters.AddWithValue("Sandbox", settings.Sandbox);
1949 cmd.Parameters.AddWithValue("SunVectorX", settings.SunVector.X);
1950 cmd.Parameters.AddWithValue("SunVectorY", settings.SunVector.Y);
1951 cmd.Parameters.AddWithValue("SunVectorZ", settings.SunVector.Z);
1952 cmd.Parameters.AddWithValue("FixedSun", settings.FixedSun);
1953 cmd.Parameters.AddWithValue("SunPosition", settings.SunPosition);
1954 cmd.Parameters.AddWithValue("Covenant", settings.Covenant.ToString());
1955 cmd.Parameters.AddWithValue("CovenantChangedDateTime", settings.CovenantChangedDateTime);
1956 cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime);
1957 cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID);
1958 cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID);
1959 cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch);
1960 cmd.Parameters.AddWithValue("casino", settings.Casino);
1961
1962 cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID);
1963 cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject);
1964 }
1965
1966 /// <summary>
1967 ///
1968 /// </summary>
1969 /// <param name="row"></param>
1970 /// <param name="land"></param>
1971 /// <param name="regionUUID"></param>
1972 private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID regionUUID)
1973 {
1974 cmd.Parameters.AddWithValue("UUID", land.GlobalID.ToString());
1975 cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString());
1976 cmd.Parameters.AddWithValue("LocalLandID", land.LocalID);
1977
1978 // Bitmap is a byte[512]
1979 cmd.Parameters.AddWithValue("Bitmap", land.Bitmap);
1980
1981 cmd.Parameters.AddWithValue("Name", land.Name);
1982 cmd.Parameters.AddWithValue("Description", land.Description);
1983 cmd.Parameters.AddWithValue("OwnerUUID", land.OwnerID.ToString());
1984 cmd.Parameters.AddWithValue("IsGroupOwned", land.IsGroupOwned);
1985 cmd.Parameters.AddWithValue("Area", land.Area);
1986 cmd.Parameters.AddWithValue("AuctionID", land.AuctionID); //Unemplemented
1987 cmd.Parameters.AddWithValue("Category", land.Category); //Enum libsecondlife.Parcel.ParcelCategory
1988 cmd.Parameters.AddWithValue("ClaimDate", land.ClaimDate);
1989 cmd.Parameters.AddWithValue("ClaimPrice", land.ClaimPrice);
1990 cmd.Parameters.AddWithValue("GroupUUID", land.GroupID.ToString());
1991 cmd.Parameters.AddWithValue("SalePrice", land.SalePrice);
1992 cmd.Parameters.AddWithValue("LandStatus", land.Status); //Enum. libsecondlife.Parcel.ParcelStatus
1993 cmd.Parameters.AddWithValue("LandFlags", land.Flags);
1994 cmd.Parameters.AddWithValue("LandingType", land.LandingType);
1995 cmd.Parameters.AddWithValue("MediaAutoScale", land.MediaAutoScale);
1996 cmd.Parameters.AddWithValue("MediaTextureUUID", land.MediaID.ToString());
1997 cmd.Parameters.AddWithValue("MediaURL", land.MediaURL);
1998 cmd.Parameters.AddWithValue("MusicURL", land.MusicURL);
1999 cmd.Parameters.AddWithValue("PassHours", land.PassHours);
2000 cmd.Parameters.AddWithValue("PassPrice", land.PassPrice);
2001 cmd.Parameters.AddWithValue("SnapshotUUID", land.SnapshotID.ToString());
2002 cmd.Parameters.AddWithValue("UserLocationX", land.UserLocation.X);
2003 cmd.Parameters.AddWithValue("UserLocationY", land.UserLocation.Y);
2004 cmd.Parameters.AddWithValue("UserLocationZ", land.UserLocation.Z);
2005 cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X);
2006 cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y);
2007 cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z);
2008 cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID);
2009 cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime);
2010 cmd.Parameters.AddWithValue("Dwell", land.Dwell);
2011 cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription);
2012 cmd.Parameters.AddWithValue("MediaType", land.MediaType);
2013 cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth);
2014 cmd.Parameters.AddWithValue("MediaHeight", land.MediaHeight);
2015 cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop);
2016 cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic);
2017 cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia);
2018 cmd.Parameters.AddWithValue("SeeAVs", land.SeeAVs ? 1 : 0);
2019 cmd.Parameters.AddWithValue("AnyAVSounds", land.AnyAVSounds ? 1 : 0);
2020 cmd.Parameters.AddWithValue("GroupAVSounds", land.GroupAVSounds ? 1 : 0);
2021
2022 }
2023
2024 /// <summary>
2025 ///
2026 /// </summary>
2027 /// <param name="row"></param>
2028 /// <param name="entry"></param>
2029 /// <param name="parcelID"></param>
2030 private static void FillLandAccessCommand(MySqlCommand cmd, LandAccessEntry entry, UUID parcelID)
2031 {
2032 cmd.Parameters.AddWithValue("LandUUID", parcelID.ToString());
2033 cmd.Parameters.AddWithValue("AccessUUID", entry.AgentID.ToString());
2034 cmd.Parameters.AddWithValue("Flags", entry.Flags);
2035 cmd.Parameters.AddWithValue("Expires", entry.Expires.ToString());
2036 }
2037
2038 /// <summary>
2039 ///
2040 /// </summary>
2041 /// <param name="row"></param>
2042 /// <returns></returns>
2043 private PrimitiveBaseShape BuildShape(IDataReader row)
2044 {
2045 PrimitiveBaseShape s = new PrimitiveBaseShape();
2046 s.Scale = new Vector3(
2047 (float)(double)row["ScaleX"],
2048 (float)(double)row["ScaleY"],
2049 (float)(double)row["ScaleZ"]
2050 );
2051 // paths
2052 s.PCode = (byte)(int)row["PCode"];
2053 s.PathBegin = (ushort)(int)row["PathBegin"];
2054 s.PathEnd = (ushort)(int)row["PathEnd"];
2055 s.PathScaleX = (byte)(int)row["PathScaleX"];
2056 s.PathScaleY = (byte)(int)row["PathScaleY"];
2057 s.PathShearX = (byte)(int)row["PathShearX"];
2058 s.PathShearY = (byte)(int)row["PathShearY"];
2059 s.PathSkew = (sbyte)(int)row["PathSkew"];
2060 s.PathCurve = (byte)(int)row["PathCurve"];
2061 s.PathRadiusOffset = (sbyte)(int)row["PathRadiusOffset"];
2062 s.PathRevolutions = (byte)(int)row["PathRevolutions"];
2063 s.PathTaperX = (sbyte)(int)row["PathTaperX"];
2064 s.PathTaperY = (sbyte)(int)row["PathTaperY"];
2065 s.PathTwist = (sbyte)(int)row["PathTwist"];
2066 s.PathTwistBegin = (sbyte)(int)row["PathTwistBegin"];
2067 // profile
2068 s.ProfileBegin = (ushort)(int)row["ProfileBegin"];
2069 s.ProfileEnd = (ushort)(int)row["ProfileEnd"];
2070 s.ProfileCurve = (byte)(int)row["ProfileCurve"];
2071 s.ProfileHollow = (ushort)(int)row["ProfileHollow"];
2072 s.TextureEntry = (byte[])row["Texture"];
2073
2074 s.ExtraParams = (byte[])row["ExtraParams"];
2075
2076 s.State = (byte)(int)row["State"];
2077 s.LastAttachPoint = (byte)(int)row["LastAttachPoint"];
2078
2079 if (!(row["Media"] is System.DBNull))
2080 s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
2081
2082 return s;
2083 }
2084
2085 /// <summary>
2086 ///
2087 /// </summary>
2088 /// <param name="row"></param>
2089 /// <param name="prim"></param>
2090 private void FillShapeCommand(MySqlCommand cmd, SceneObjectPart prim)
2091 {
2092 PrimitiveBaseShape s = prim.Shape;
2093 cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString());
2094 // shape is an enum
2095 cmd.Parameters.AddWithValue("Shape", 0);
2096 // vectors
2097 cmd.Parameters.AddWithValue("ScaleX", (double)s.Scale.X);
2098 cmd.Parameters.AddWithValue("ScaleY", (double)s.Scale.Y);
2099 cmd.Parameters.AddWithValue("ScaleZ", (double)s.Scale.Z);
2100 // paths
2101 cmd.Parameters.AddWithValue("PCode", s.PCode);
2102 cmd.Parameters.AddWithValue("PathBegin", s.PathBegin);
2103 cmd.Parameters.AddWithValue("PathEnd", s.PathEnd);
2104 cmd.Parameters.AddWithValue("PathScaleX", s.PathScaleX);
2105 cmd.Parameters.AddWithValue("PathScaleY", s.PathScaleY);
2106 cmd.Parameters.AddWithValue("PathShearX", s.PathShearX);
2107 cmd.Parameters.AddWithValue("PathShearY", s.PathShearY);
2108 cmd.Parameters.AddWithValue("PathSkew", s.PathSkew);
2109 cmd.Parameters.AddWithValue("PathCurve", s.PathCurve);
2110 cmd.Parameters.AddWithValue("PathRadiusOffset", s.PathRadiusOffset);
2111 cmd.Parameters.AddWithValue("PathRevolutions", s.PathRevolutions);
2112 cmd.Parameters.AddWithValue("PathTaperX", s.PathTaperX);
2113 cmd.Parameters.AddWithValue("PathTaperY", s.PathTaperY);
2114 cmd.Parameters.AddWithValue("PathTwist", s.PathTwist);
2115 cmd.Parameters.AddWithValue("PathTwistBegin", s.PathTwistBegin);
2116 // profile
2117 cmd.Parameters.AddWithValue("ProfileBegin", s.ProfileBegin);
2118 cmd.Parameters.AddWithValue("ProfileEnd", s.ProfileEnd);
2119 cmd.Parameters.AddWithValue("ProfileCurve", s.ProfileCurve);
2120 cmd.Parameters.AddWithValue("ProfileHollow", s.ProfileHollow);
2121 cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
2122 cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
2123 cmd.Parameters.AddWithValue("State", s.State);
2124 cmd.Parameters.AddWithValue("LastAttachPoint", s.LastAttachPoint);
2125 cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
2126 }
2127
2128 public virtual void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
2129 {
2130 lock (m_dbLock)
2131 {
2132 RemoveItems(primID);
2133
2134 if (items.Count == 0)
2135 return;
2136
2137 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2138 {
2139 dbcon.Open();
2140
2141 using (MySqlCommand cmd = dbcon.CreateCommand())
2142 {
2143 cmd.CommandText = "insert into primitems (" +
2144 "invType, assetType, name, " +
2145 "description, creationDate, nextPermissions, " +
2146 "currentPermissions, basePermissions, " +
2147 "everyonePermissions, groupPermissions, " +
2148 "flags, itemID, primID, assetID, " +
2149 "parentFolderID, creatorID, ownerID, " +
2150 "groupID, lastOwnerID) values (?invType, " +
2151 "?assetType, ?name, ?description, " +
2152 "?creationDate, ?nextPermissions, " +
2153 "?currentPermissions, ?basePermissions, " +
2154 "?everyonePermissions, ?groupPermissions, " +
2155 "?flags, ?itemID, ?primID, ?assetID, " +
2156 "?parentFolderID, ?creatorID, ?ownerID, " +
2157 "?groupID, ?lastOwnerID)";
2158
2159 foreach (TaskInventoryItem item in items)
2160 {
2161 cmd.Parameters.Clear();
2162
2163 FillItemCommand(cmd, item);
2164
2165 ExecuteNonQuery(cmd);
2166 }
2167 }
2168 dbcon.Close();
2169 }
2170 }
2171 }
2172
2173 public UUID[] GetObjectIDs(UUID regionID)
2174 {
2175 List<UUID> uuids = new List<UUID>();
2176
2177 lock (m_dbLock)
2178 {
2179 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2180 {
2181 dbcon.Open();
2182
2183 using (MySqlCommand cmd = dbcon.CreateCommand())
2184 {
2185 cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID and SceneGroupID = UUID";
2186 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
2187
2188 using (IDataReader reader = ExecuteReader(cmd))
2189 {
2190 while (reader.Read())
2191 {
2192 UUID id = new UUID(reader["UUID"].ToString());
2193
2194 uuids.Add(id);
2195 }
2196 }
2197 }
2198 dbcon.Close();
2199 }
2200 }
2201
2202 return uuids.ToArray();
2203 }
2204
2205 private void LoadSpawnPoints(RegionSettings rs)
2206 {
2207 rs.ClearSpawnPoints();
2208
2209 lock (m_dbLock)
2210 {
2211 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2212 {
2213 dbcon.Open();
2214
2215 using (MySqlCommand cmd = dbcon.CreateCommand())
2216 {
2217 cmd.CommandText = "select Yaw, Pitch, Distance from spawn_points where RegionID = ?RegionID";
2218 cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString());
2219
2220 using (IDataReader r = cmd.ExecuteReader())
2221 {
2222 while (r.Read())
2223 {
2224 SpawnPoint sp = new SpawnPoint();
2225
2226 sp.Yaw = (float)r["Yaw"];
2227 sp.Pitch = (float)r["Pitch"];
2228 sp.Distance = (float)r["Distance"];
2229
2230 rs.AddSpawnPoint(sp);
2231 }
2232 }
2233 }
2234 dbcon.Close();
2235 }
2236 }
2237 }
2238
2239 private void SaveSpawnPoints(RegionSettings rs)
2240 {
2241 lock (m_dbLock)
2242 {
2243 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2244 {
2245 dbcon.Open();
2246
2247 using (MySqlCommand cmd = dbcon.CreateCommand())
2248 {
2249 cmd.CommandText = "delete from spawn_points where RegionID = ?RegionID";
2250 cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString());
2251
2252 cmd.ExecuteNonQuery();
2253
2254 cmd.Parameters.Clear();
2255
2256 cmd.CommandText = "insert into spawn_points (RegionID, Yaw, Pitch, Distance) values ( ?RegionID, ?Yaw, ?Pitch, ?Distance)";
2257
2258 foreach (SpawnPoint p in rs.SpawnPoints())
2259 {
2260 cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString());
2261 cmd.Parameters.AddWithValue("?Yaw", p.Yaw);
2262 cmd.Parameters.AddWithValue("?Pitch", p.Pitch);
2263 cmd.Parameters.AddWithValue("?Distance", p.Distance);
2264
2265 cmd.ExecuteNonQuery();
2266 cmd.Parameters.Clear();
2267 }
2268 }
2269 dbcon.Close();
2270 }
2271 }
2272 }
2273
2274 public void SaveExtra(UUID regionID, string name, string val)
2275 {
2276 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2277 {
2278 dbcon.Open();
2279
2280 using (MySqlCommand cmd = dbcon.CreateCommand())
2281 {
2282 cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
2283 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
2284 cmd.Parameters.AddWithValue("?Name", name);
2285 cmd.Parameters.AddWithValue("?value", val);
2286
2287 cmd.ExecuteNonQuery();
2288 }
2289 dbcon.Close();
2290 }
2291 }
2292
2293 public void RemoveExtra(UUID regionID, string name)
2294 {
2295 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2296 {
2297 dbcon.Open();
2298
2299 using (MySqlCommand cmd = dbcon.CreateCommand())
2300 {
2301 cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
2302 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
2303 cmd.Parameters.AddWithValue("?Name", name);
2304
2305 cmd.ExecuteNonQuery();
2306 }
2307 dbcon.Close();
2308 }
2309 }
2310
2311 public Dictionary<string, string> GetExtra(UUID regionID)
2312 {
2313 Dictionary<string, string> ret = new Dictionary<string, string>();
2314
2315 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
2316 {
2317 dbcon.Open();
2318
2319 using (MySqlCommand cmd = dbcon.CreateCommand())
2320 {
2321 cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
2322 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
2323 using (IDataReader r = cmd.ExecuteReader())
2324 {
2325 while (r.Read())
2326 {
2327 ret[r["Name"].ToString()] = r["value"].ToString();
2328 }
2329 }
2330 }
2331 dbcon.Close();
2332 }
2333
2334 return ret;
2335 }
2336 }
2337}
diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs
new file mode 100644
index 0000000..59cfe70
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs
@@ -0,0 +1,105 @@
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 MySqlUserAccountData : MySQLGenericTableHandler<UserAccountData>, IUserAccountData
39 {
40 public MySqlUserAccountData(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 bool valid = false;
50
51 for (int i = 0 ; i < words.Length ; i++)
52 {
53 if (words[i].Length > 2)
54 valid = true;
55// if (words[i].Length < 3)
56// {
57// if (i != words.Length - 1)
58// Array.Copy(words, i + 1, words, i, words.Length - i - 1);
59// Array.Resize(ref words, words.Length - 1);
60// }
61 }
62
63 if ((!valid) || words.Length == 0)
64 return new UserAccountData[0];
65
66 if (words.Length > 2)
67 return new UserAccountData[0];
68
69 using (MySqlCommand cmd = new MySqlCommand())
70 {
71 if (words.Length == 1)
72 {
73 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) and active=1", m_Realm);
74 cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
75 cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
76 }
77 else
78 {
79 cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm);
80 cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
81 cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
82 cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
83 }
84
85 return DoQuery(cmd);
86 }
87 }
88
89 public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
90 {
91 using (MySqlCommand cmd = new MySqlCommand())
92 {
93 if (scopeID != UUID.Zero)
94 {
95 where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
96 cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
97 }
98
99 cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
100
101 return DoQuery(cmd);
102 }
103 }
104 }
105}
diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
new file mode 100644
index 0000000..16637c3
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
@@ -0,0 +1,1030 @@
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 OpenSim.Data;
32using OpenSim.Framework;
33using MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using log4net;
37
38namespace OpenSim.Data.MySQL
39{
40 public class UserProfilesData: IProfilesData
41 {
42 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 #region Properites
45 string ConnectionString
46 {
47 get; set;
48 }
49
50 protected virtual Assembly Assembly
51 {
52 get { return GetType().Assembly; }
53 }
54
55 #endregion Properties
56
57 #region class Member Functions
58 public UserProfilesData(string connectionString)
59 {
60 ConnectionString = connectionString;
61 Init();
62 }
63
64 void Init()
65 {
66 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
67 {
68 dbcon.Open();
69
70 Migration m = new Migration(dbcon, Assembly, "UserProfiles");
71 m.Update();
72 dbcon.Close();
73 }
74 }
75 #endregion Member Functions
76
77 #region Classifieds Queries
78 /// <summary>
79 /// Gets the classified records.
80 /// </summary>
81 /// <returns>
82 /// Array of classified records
83 /// </returns>
84 /// <param name='creatorId'>
85 /// Creator identifier.
86 /// </param>
87 public OSDArray GetClassifiedRecords(UUID creatorId)
88 {
89 OSDArray data = new OSDArray();
90
91 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
92 {
93 const string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id";
94 dbcon.Open();
95 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
96 {
97 cmd.Parameters.AddWithValue("?Id", creatorId);
98 using( MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
99 {
100 if(reader.HasRows)
101 {
102 while (reader.Read())
103 {
104 OSDMap n = new OSDMap();
105 UUID Id = UUID.Zero;
106
107 string Name = null;
108 try
109 {
110 UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id);
111 Name = Convert.ToString(reader["name"]);
112 }
113 catch (Exception e)
114 {
115 m_log.ErrorFormat("[PROFILES_DATA] GetClassifiedRecords exception {0}", e.Message);
116 }
117 n.Add("classifieduuid", OSD.FromUUID(Id));
118 n.Add("name", OSD.FromString(Name));
119 data.Add(n);
120 }
121 }
122 }
123 }
124 dbcon.Close();
125 }
126 return data;
127 }
128
129 public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result)
130 {
131 const string query =
132 "INSERT INTO classifieds ("
133 + "`classifieduuid`,"
134 + "`creatoruuid`,"
135 + "`creationdate`,"
136 + "`expirationdate`,"
137 + "`category`,"
138 + "`name`,"
139 + "`description`,"
140 + "`parceluuid`,"
141 + "`parentestate`,"
142 + "`snapshotuuid`,"
143 + "`simname`,"
144 + "`posglobal`,"
145 + "`parcelname`,"
146 + "`classifiedflags`,"
147 + "`priceforlisting`) "
148 + "VALUES ("
149 + "?ClassifiedId,"
150 + "?CreatorId,"
151 + "?CreatedDate,"
152 + "?ExpirationDate,"
153 + "?Category,"
154 + "?Name,"
155 + "?Description,"
156 + "?ParcelId,"
157 + "?ParentEstate,"
158 + "?SnapshotId,"
159 + "?SimName,"
160 + "?GlobalPos,"
161 + "?ParcelName,"
162 + "?Flags,"
163 + "?ListingPrice ) "
164 + "ON DUPLICATE KEY UPDATE "
165 + "category=?Category, "
166 + "expirationdate=?ExpirationDate, "
167 + "name=?Name, "
168 + "description=?Description, "
169 + "parentestate=?ParentEstate, "
170 + "posglobal=?GlobalPos, "
171 + "parcelname=?ParcelName, "
172 + "classifiedflags=?Flags, "
173 + "priceforlisting=?ListingPrice, "
174 + "snapshotuuid=?SnapshotId"
175 ;
176
177 if(string.IsNullOrEmpty(ad.ParcelName))
178 ad.ParcelName = "Unknown";
179 if(ad.ParcelId == null)
180 ad.ParcelId = UUID.Zero;
181 if(string.IsNullOrEmpty(ad.Description))
182 ad.Description = "No Description";
183
184 DateTime epoch = new DateTime(1970, 1, 1);
185 DateTime now = DateTime.Now;
186 TimeSpan epochnow = now - epoch;
187 TimeSpan duration;
188 DateTime expiration;
189 TimeSpan epochexp;
190
191 if(ad.Flags == 2)
192 {
193 duration = new TimeSpan(7,0,0,0);
194 expiration = now.Add(duration);
195 epochexp = expiration - epoch;
196 }
197 else
198 {
199 duration = new TimeSpan(365,0,0,0);
200 expiration = now.Add(duration);
201 epochexp = expiration - epoch;
202 }
203 ad.CreationDate = (int)epochnow.TotalSeconds;
204 ad.ExpirationDate = (int)epochexp.TotalSeconds;
205
206 try
207 {
208 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
209 {
210 dbcon.Open();
211 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
212 {
213 cmd.Parameters.AddWithValue("?ClassifiedId", ad.ClassifiedId.ToString());
214 cmd.Parameters.AddWithValue("?CreatorId", ad.CreatorId.ToString());
215 cmd.Parameters.AddWithValue("?CreatedDate", ad.CreationDate.ToString());
216 cmd.Parameters.AddWithValue("?ExpirationDate", ad.ExpirationDate.ToString());
217 cmd.Parameters.AddWithValue("?Category", ad.Category.ToString());
218 cmd.Parameters.AddWithValue("?Name", ad.Name.ToString());
219 cmd.Parameters.AddWithValue("?Description", ad.Description.ToString());
220 cmd.Parameters.AddWithValue("?ParcelId", ad.ParcelId.ToString());
221 cmd.Parameters.AddWithValue("?ParentEstate", ad.ParentEstate.ToString());
222 cmd.Parameters.AddWithValue("?SnapshotId", ad.SnapshotId.ToString ());
223 cmd.Parameters.AddWithValue("?SimName", ad.SimName.ToString());
224 cmd.Parameters.AddWithValue("?GlobalPos", ad.GlobalPos.ToString());
225 cmd.Parameters.AddWithValue("?ParcelName", ad.ParcelName.ToString());
226 cmd.Parameters.AddWithValue("?Flags", ad.Flags.ToString());
227 cmd.Parameters.AddWithValue("?ListingPrice", ad.Price.ToString ());
228
229 cmd.ExecuteNonQuery();
230 }
231 dbcon.Close();
232 }
233 }
234 catch (Exception e)
235 {
236 m_log.ErrorFormat("[PROFILES_DATA]: UpdateClassifiedRecord exception {0}", e.Message);
237 result = e.Message;
238 return false;
239 }
240 return true;
241 }
242
243 public bool DeleteClassifiedRecord(UUID recordId)
244 {
245 const string query = "DELETE FROM classifieds WHERE classifieduuid = ?recordId";
246
247 try
248 {
249 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
250 {
251 dbcon.Open();
252
253 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
254 {
255 cmd.Parameters.AddWithValue("?recordId", recordId.ToString());
256 cmd.ExecuteNonQuery();
257 }
258 dbcon.Close();
259 }
260 }
261 catch (Exception e)
262 {
263 m_log.ErrorFormat("[PROFILES_DATA]: DeleteClassifiedRecord exception {0}", e.Message);
264 return false;
265 }
266 return true;
267 }
268
269 public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result)
270 {
271
272 const string query = "SELECT * FROM classifieds WHERE classifieduuid = ?AdId";
273
274 try
275 {
276 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
277 {
278 dbcon.Open();
279 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
280 {
281 cmd.Parameters.AddWithValue("?AdId", ad.ClassifiedId.ToString());
282
283 using (MySqlDataReader reader = cmd.ExecuteReader())
284 {
285 if(reader.Read ())
286 {
287 ad.CreatorId = new UUID(reader.GetGuid("creatoruuid"));
288 ad.ParcelId = new UUID(reader.GetGuid("parceluuid"));
289 ad.SnapshotId = new UUID(reader.GetGuid("snapshotuuid"));
290 ad.CreationDate = Convert.ToInt32(reader["creationdate"]);
291 ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]);
292 ad.ParentEstate = Convert.ToInt32(reader["parentestate"]);
293 ad.Flags = (byte)reader.GetUInt32("classifiedflags");
294 ad.Category = reader.GetInt32("category");
295 ad.Price = reader.GetInt16("priceforlisting");
296 ad.Name = reader.GetString("name");
297 ad.Description = reader.GetString("description");
298 ad.SimName = reader.GetString("simname");
299 ad.GlobalPos = reader.GetString("posglobal");
300 ad.ParcelName = reader.GetString("parcelname");
301
302 }
303 }
304 }
305 dbcon.Close();
306 }
307 }
308 catch (Exception e)
309 {
310 m_log.ErrorFormat("[PROFILES_DATA]: GetClassifiedInfo exception {0}", e.Message);
311 }
312 return true;
313 }
314 #endregion Classifieds Queries
315
316 #region Picks Queries
317 public OSDArray GetAvatarPicks(UUID avatarId)
318 {
319 const string query = "SELECT `pickuuid`,`name` FROM userpicks WHERE creatoruuid = ?Id";
320
321 OSDArray data = new OSDArray();
322
323 try
324 {
325 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
326 {
327 dbcon.Open();
328 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
329 {
330 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
331
332 using (MySqlDataReader reader = cmd.ExecuteReader())
333 {
334 if(reader.HasRows)
335 {
336 while (reader.Read())
337 {
338 OSDMap record = new OSDMap();
339
340 record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"]));
341 record.Add("name",OSD.FromString((string)reader["name"]));
342 data.Add(record);
343 }
344 }
345 }
346 }
347 dbcon.Close();
348 }
349 }
350 catch (Exception e)
351 {
352 m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarPicks exception {0}", e.Message);
353 }
354 return data;
355 }
356
357 public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId)
358 {
359 UserProfilePick pick = new UserProfilePick();
360 const string query = "SELECT * FROM userpicks WHERE creatoruuid = ?CreatorId AND pickuuid = ?PickId";
361
362 try
363 {
364 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
365 {
366 dbcon.Open();
367 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
368 {
369 cmd.Parameters.AddWithValue("?CreatorId", avatarId.ToString());
370 cmd.Parameters.AddWithValue("?PickId", pickId.ToString());
371
372 using (MySqlDataReader reader = cmd.ExecuteReader())
373 {
374 if(reader.HasRows)
375 {
376 reader.Read();
377
378 string description = (string)reader["description"];
379
380 if (string.IsNullOrEmpty(description))
381 description = "No description given.";
382
383 UUID.TryParse((string)reader["pickuuid"], out pick.PickId);
384 UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId);
385 UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
386 UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
387 pick.GlobalPos = (string)reader["posglobal"];
388 pick.Gatekeeper = (string)reader["gatekeeper"];
389 bool.TryParse((string)reader["toppick"], out pick.TopPick);
390 bool.TryParse((string)reader["enabled"], out pick.Enabled);
391 pick.Name = (string)reader["name"];
392 pick.Desc = description;
393 pick.ParcelName = (string)reader["user"];
394 pick.OriginalName = (string)reader["originalname"];
395 pick.SimName = (string)reader["simname"];
396 pick.SortOrder = (int)reader["sortorder"];
397 }
398 }
399 }
400 dbcon.Close();
401 }
402 }
403 catch (Exception e)
404 {
405 m_log.ErrorFormat("[PROFILES_DATA]: GetPickInfo exception {0}", e.Message);
406 }
407 return pick;
408 }
409
410 public bool UpdatePicksRecord(UserProfilePick pick)
411 {
412 const string query =
413 "INSERT INTO userpicks VALUES ("
414 + "?PickId,"
415 + "?CreatorId,"
416 + "?TopPick,"
417 + "?ParcelId,"
418 + "?Name,"
419 + "?Desc,"
420 + "?SnapshotId,"
421 + "?User,"
422 + "?Original,"
423 + "?SimName,"
424 + "?GlobalPos,"
425 + "?SortOrder,"
426 + "?Enabled,"
427 + "?Gatekeeper)"
428 + "ON DUPLICATE KEY UPDATE "
429 + "parceluuid=?ParcelId,"
430 + "name=?Name,"
431 + "description=?Desc,"
432 + "user=?User,"
433 + "simname=?SimName,"
434 + "snapshotuuid=?SnapshotId,"
435 + "pickuuid=?PickId,"
436 + "posglobal=?GlobalPos,"
437 + "gatekeeper=?Gatekeeper"
438 ;
439
440 try
441 {
442 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
443 {
444 dbcon.Open();
445 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
446 {
447 cmd.Parameters.AddWithValue("?PickId", pick.PickId.ToString());
448 cmd.Parameters.AddWithValue("?CreatorId", pick.CreatorId.ToString());
449 cmd.Parameters.AddWithValue("?TopPick", pick.TopPick.ToString());
450 cmd.Parameters.AddWithValue("?ParcelId", pick.ParcelId.ToString());
451 cmd.Parameters.AddWithValue("?Name", pick.Name.ToString());
452 cmd.Parameters.AddWithValue("?Desc", pick.Desc.ToString());
453 cmd.Parameters.AddWithValue("?SnapshotId", pick.SnapshotId.ToString());
454 cmd.Parameters.AddWithValue("?User", pick.ParcelName.ToString());
455 cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString());
456 cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString());
457 cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos);
458 cmd.Parameters.AddWithValue("?Gatekeeper",pick.Gatekeeper);
459 cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ());
460 cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString());
461
462 cmd.ExecuteNonQuery();
463 }
464 dbcon.Close();
465 }
466 }
467 catch (Exception e)
468 {
469 m_log.ErrorFormat("[PROFILES_DATA]: UpdatePicksRecord exception {0}", e.Message);
470 return false;
471 }
472 return true;
473 }
474
475 public bool DeletePicksRecord(UUID pickId)
476 {
477 string query = "DELETE FROM userpicks WHERE pickuuid = ?PickId";
478
479 try
480 {
481 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
482 {
483 dbcon.Open();
484
485 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
486 {
487 cmd.Parameters.AddWithValue("?PickId", pickId.ToString());
488
489 cmd.ExecuteNonQuery();
490 }
491 dbcon.Close();
492 }
493 }
494 catch (Exception e)
495 {
496 m_log.ErrorFormat("[PROFILES_DATA]: DeletePicksRecord exception {0}", e.Message);
497 return false;
498 }
499 return true;
500 }
501 #endregion Picks Queries
502
503 #region Avatar Notes Queries
504 public bool GetAvatarNotes(ref UserProfileNotes notes)
505 { // WIP
506 const string query = "SELECT `notes` FROM usernotes WHERE useruuid = ?Id AND targetuuid = ?TargetId";
507
508 try
509 {
510 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
511 {
512 dbcon.Open();
513 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
514 {
515 cmd.Parameters.AddWithValue("?Id", notes.UserId.ToString());
516 cmd.Parameters.AddWithValue("?TargetId", notes.TargetId.ToString());
517
518 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
519 {
520 if(reader.HasRows)
521 {
522 reader.Read();
523 notes.Notes = OSD.FromString((string)reader["notes"]);
524 }
525 else
526 {
527 notes.Notes = OSD.FromString("");
528 }
529 }
530 }
531 dbcon.Close();
532 }
533 }
534 catch (Exception e)
535 {
536 m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarNotes exception {0}", e.Message);
537 }
538 return true;
539 }
540
541 public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result)
542 {
543 string query;
544 bool remove;
545
546 if(string.IsNullOrEmpty(note.Notes))
547 {
548 remove = true;
549 query = "DELETE FROM usernotes WHERE useruuid=?UserId AND targetuuid=?TargetId";
550 }
551 else
552 {
553 remove = false;
554 query = "INSERT INTO usernotes VALUES ("
555 + "?UserId,"
556 + "?TargetId,"
557 + "?Notes )"
558 + "ON DUPLICATE KEY "
559 + "UPDATE "
560 + "notes=?Notes"
561 ;
562 }
563
564 try
565 {
566 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
567 {
568 dbcon.Open();
569 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
570 {
571 if(!remove)
572 cmd.Parameters.AddWithValue("?Notes", note.Notes);
573 cmd.Parameters.AddWithValue("?TargetId", note.TargetId.ToString ());
574 cmd.Parameters.AddWithValue("?UserId", note.UserId.ToString());
575
576 cmd.ExecuteNonQuery();
577 }
578 dbcon.Close();
579 }
580 }
581 catch (Exception e)
582 {
583 m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarNotes exception {0}", e.Message);
584 return false;
585 }
586 return true;
587
588 }
589 #endregion Avatar Notes Queries
590
591 #region Avatar Properties
592 public bool GetAvatarProperties(ref UserProfileProperties props, ref string result)
593 {
594 string query = "SELECT * FROM userprofile WHERE useruuid = ?Id";
595
596 try
597 {
598 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
599 {
600 dbcon.Open();
601 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
602 {
603 cmd.Parameters.AddWithValue("?Id", props.UserId.ToString());
604
605 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
606 {
607 if(reader.HasRows)
608 {
609 m_log.DebugFormat("[PROFILES_DATA]" +
610 ": Getting data for {0}.", props.UserId);
611 reader.Read();
612 props.WebUrl = (string)reader["profileURL"];
613 UUID.TryParse((string)reader["profileImage"], out props.ImageId);
614 props.AboutText = (string)reader["profileAboutText"];
615 UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId);
616 props.FirstLifeText = (string)reader["profileFirstText"];
617 UUID.TryParse((string)reader["profilePartner"], out props.PartnerId);
618 props.WantToMask = (int)reader["profileWantToMask"];
619 props.WantToText = (string)reader["profileWantToText"];
620 props.SkillsMask = (int)reader["profileSkillsMask"];
621 props.SkillsText = (string)reader["profileSkillsText"];
622 props.Language = (string)reader["profileLanguages"];
623 }
624 else
625 {
626 m_log.DebugFormat("[PROFILES_DATA]" +
627 ": No data for {0}", props.UserId);
628
629 props.WebUrl = string.Empty;
630 props.ImageId = UUID.Zero;
631 props.AboutText = string.Empty;
632 props.FirstLifeImageId = UUID.Zero;
633 props.FirstLifeText = string.Empty;
634 props.PartnerId = UUID.Zero;
635 props.WantToMask = 0;
636 props.WantToText = string.Empty;
637 props.SkillsMask = 0;
638 props.SkillsText = string.Empty;
639 props.Language = string.Empty;
640 props.PublishProfile = false;
641 props.PublishMature = false;
642
643 query = "INSERT INTO userprofile ("
644 + "useruuid, "
645 + "profilePartner, "
646 + "profileAllowPublish, "
647 + "profileMaturePublish, "
648 + "profileURL, "
649 + "profileWantToMask, "
650 + "profileWantToText, "
651 + "profileSkillsMask, "
652 + "profileSkillsText, "
653 + "profileLanguages, "
654 + "profileImage, "
655 + "profileAboutText, "
656 + "profileFirstImage, "
657 + "profileFirstText) VALUES ("
658 + "?userId, "
659 + "?profilePartner, "
660 + "?profileAllowPublish, "
661 + "?profileMaturePublish, "
662 + "?profileURL, "
663 + "?profileWantToMask, "
664 + "?profileWantToText, "
665 + "?profileSkillsMask, "
666 + "?profileSkillsText, "
667 + "?profileLanguages, "
668 + "?profileImage, "
669 + "?profileAboutText, "
670 + "?profileFirstImage, "
671 + "?profileFirstText)"
672 ;
673
674 dbcon.Close();
675 dbcon.Open();
676
677 using (MySqlCommand put = new MySqlCommand(query, dbcon))
678 {
679 put.Parameters.AddWithValue("?userId", props.UserId.ToString());
680 put.Parameters.AddWithValue("?profilePartner", props.PartnerId.ToString());
681 put.Parameters.AddWithValue("?profileAllowPublish", props.PublishProfile);
682 put.Parameters.AddWithValue("?profileMaturePublish", props.PublishMature);
683 put.Parameters.AddWithValue("?profileURL", props.WebUrl);
684 put.Parameters.AddWithValue("?profileWantToMask", props.WantToMask);
685 put.Parameters.AddWithValue("?profileWantToText", props.WantToText);
686 put.Parameters.AddWithValue("?profileSkillsMask", props.SkillsMask);
687 put.Parameters.AddWithValue("?profileSkillsText", props.SkillsText);
688 put.Parameters.AddWithValue("?profileLanguages", props.Language);
689 put.Parameters.AddWithValue("?profileImage", props.ImageId.ToString());
690 put.Parameters.AddWithValue("?profileAboutText", props.AboutText);
691 put.Parameters.AddWithValue("?profileFirstImage", props.FirstLifeImageId.ToString());
692 put.Parameters.AddWithValue("?profileFirstText", props.FirstLifeText);
693
694 put.ExecuteNonQuery();
695 }
696 }
697 }
698 }
699 dbcon.Close();
700 }
701 }
702 catch (Exception e)
703 {
704 m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarProperties exception {0}", e.Message);
705 result = e.Message;
706 return false;
707 }
708 return true;
709 }
710
711 public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result)
712 {
713 const string query = "UPDATE userprofile SET profileURL=?profileURL,"
714 + "profileImage=?image, profileAboutText=?abouttext,"
715 + "profileFirstImage=?firstlifeimage, profileFirstText=?firstlifetext "
716 + "WHERE useruuid=?uuid";
717
718 try
719 {
720 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
721 {
722 dbcon.Open();
723 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
724 {
725 cmd.Parameters.AddWithValue("?profileURL", props.WebUrl);
726 cmd.Parameters.AddWithValue("?image", props.ImageId.ToString());
727 cmd.Parameters.AddWithValue("?abouttext", props.AboutText);
728 cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString());
729 cmd.Parameters.AddWithValue("?firstlifetext", props.FirstLifeText);
730 cmd.Parameters.AddWithValue("?uuid", props.UserId.ToString());
731
732 cmd.ExecuteNonQuery();
733 }
734 dbcon.Close();
735 }
736 }
737 catch (Exception e)
738 {
739 m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarProperties exception {0}", e.Message);
740
741 return false;
742 }
743 return true;
744 }
745 #endregion Avatar Properties
746
747 #region Avatar Interests
748 public bool UpdateAvatarInterests(UserProfileProperties up, ref string result)
749 {
750 const string query = "UPDATE userprofile SET "
751 + "profileWantToMask=?WantMask, "
752 + "profileWantToText=?WantText,"
753 + "profileSkillsMask=?SkillsMask,"
754 + "profileSkillsText=?SkillsText, "
755 + "profileLanguages=?Languages "
756 + "WHERE useruuid=?uuid";
757
758 try
759 {
760 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
761 {
762 dbcon.Open();
763 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
764 {
765 cmd.Parameters.AddWithValue("?WantMask", up.WantToMask);
766 cmd.Parameters.AddWithValue("?WantText", up.WantToText);
767 cmd.Parameters.AddWithValue("?SkillsMask", up.SkillsMask);
768 cmd.Parameters.AddWithValue("?SkillsText", up.SkillsText);
769 cmd.Parameters.AddWithValue("?Languages", up.Language);
770 cmd.Parameters.AddWithValue("?uuid", up.UserId.ToString());
771
772 cmd.ExecuteNonQuery();
773 }
774 }
775 }
776 catch (Exception e)
777 {
778 m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarInterests exception {0}", e.Message);
779 result = e.Message;
780 return false;
781 }
782 return true;
783 }
784 #endregion Avatar Interests
785
786 public OSDArray GetUserImageAssets(UUID avatarId)
787 {
788 OSDArray data = new OSDArray();
789 const string queryA = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id";
790
791 // Get classified image assets
792
793 try
794 {
795 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
796 {
797 dbcon.Open();
798
799 using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`classifieds`"), dbcon))
800 {
801 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
802
803 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
804 {
805 if(reader.HasRows)
806 {
807 while (reader.Read())
808 {
809 data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
810 }
811 }
812 }
813 }
814
815 dbcon.Close();
816 dbcon.Open();
817
818 using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`userpicks`"), dbcon))
819 {
820 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
821
822 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
823 {
824 if(reader.HasRows)
825 {
826 while (reader.Read())
827 {
828 data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
829 }
830 }
831 }
832 }
833
834 dbcon.Close();
835 dbcon.Open();
836
837 const string queryB = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id";
838
839 using (MySqlCommand cmd = new MySqlCommand(string.Format (queryB,"`userpicks`"), dbcon))
840 {
841 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
842
843 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
844 {
845 if(reader.HasRows)
846 {
847 while (reader.Read())
848 {
849 data.Add(new OSDString((string)reader["profileImage"].ToString ()));
850 data.Add(new OSDString((string)reader["profileFirstImage"].ToString ()));
851 }
852 }
853 }
854 }
855 dbcon.Close();
856 }
857 }
858 catch (Exception e)
859 {
860 m_log.ErrorFormat("[PROFILES_DATA]: GetUserImageAssets exception {0}", e.Message);
861 }
862 return data;
863 }
864
865 #region User Preferences
866 public bool GetUserPreferences(ref UserPreferences pref, ref string result)
867 {
868 const string query = "SELECT imviaemail,visible,email FROM usersettings WHERE useruuid = ?Id";
869
870 try
871 {
872 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
873 {
874 dbcon.Open();
875 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
876 {
877 cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString());
878 using (MySqlDataReader reader = cmd.ExecuteReader())
879 {
880 if (reader.HasRows)
881 {
882 reader.Read();
883 bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
884 bool.TryParse((string)reader["visible"], out pref.Visible);
885 pref.EMail = (string)reader["email"];
886 }
887 else
888 {
889 dbcon.Close();
890 dbcon.Open();
891
892 const string queryB = "INSERT INTO usersettings VALUES (?uuid,'false','false', ?Email)";
893
894 using (MySqlCommand put = new MySqlCommand(queryB, dbcon))
895 {
896
897 put.Parameters.AddWithValue("?Email", pref.EMail);
898 put.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
899
900 put.ExecuteNonQuery();
901 }
902 }
903 }
904 }
905 dbcon.Close();
906 }
907 }
908 catch (Exception e)
909 {
910 m_log.ErrorFormat("[PROFILES_DATA]: GetUserPreferences exception {0}", e.Message);
911 result = e.Message;
912 return false;
913 }
914 return true;
915 }
916
917 public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
918 {
919 const string query = "UPDATE usersettings SET imviaemail=?ImViaEmail,"
920 + "visible=?Visible, email=?EMail "
921 + "WHERE useruuid=?uuid";
922
923 try
924 {
925 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
926 {
927 dbcon.Open();
928 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
929 {
930 cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower());
931 cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower());
932 cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
933 cmd.Parameters.AddWithValue("?EMail", pref.EMail.ToString().ToLower());
934
935 cmd.ExecuteNonQuery();
936 }
937 dbcon.Close();
938 }
939 }
940 catch (Exception e)
941 {
942 m_log.ErrorFormat("[PROFILES_DATA]: UpdateUserPreferences exception {0} {1}", e.Message, e.InnerException);
943 result = e.Message;
944 return false;
945 }
946 return true;
947 }
948 #endregion User Preferences
949
950 #region Integration
951 public bool GetUserAppData(ref UserAppData props, ref string result)
952 {
953 const string query = "SELECT * FROM `userdata` WHERE UserId = ?Id AND TagId = ?TagId";
954
955 try
956 {
957 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
958 {
959 dbcon.Open();
960 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
961 {
962 cmd.Parameters.AddWithValue("?Id", props.UserId.ToString());
963 cmd.Parameters.AddWithValue ("?TagId", props.TagId.ToString());
964
965 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
966 {
967 if(reader.HasRows)
968 {
969 reader.Read();
970 props.DataKey = (string)reader["DataKey"];
971 props.DataVal = (string)reader["DataVal"];
972 }
973 else
974 {
975 const string queryB = "INSERT INTO userdata VALUES (?UserId, ?TagId, ?DataKey, ?DataVal)";
976 using (MySqlCommand put = new MySqlCommand(queryB, dbcon))
977 {
978 put.Parameters.AddWithValue("?UserId", props.UserId.ToString());
979 put.Parameters.AddWithValue("?TagId", props.TagId.ToString());
980 put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
981 put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString());
982
983 put.ExecuteNonQuery();
984 }
985 }
986 }
987 }
988 dbcon.Close();
989 }
990 }
991 catch (Exception e)
992 {
993 m_log.ErrorFormat("[PROFILES_DATA]: GetUserAppData exception {0}", e.Message);
994 result = e.Message;
995 return false;
996 }
997 return true;
998 }
999
1000 public bool SetUserAppData(UserAppData props, ref string result)
1001 {
1002 const string query = "UPDATE userdata SET TagId = ?TagId, DataKey = ?DataKey, DataVal = ?DataVal WHERE UserId = ?UserId AND TagId = ?TagId";
1003
1004 try
1005 {
1006 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
1007 {
1008 dbcon.Open();
1009 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
1010 {
1011 cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString());
1012 cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString());
1013 cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
1014 cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString());
1015
1016 cmd.ExecuteNonQuery();
1017 }
1018 dbcon.Close();
1019 }
1020 }
1021 catch (Exception e)
1022 {
1023 m_log.ErrorFormat("[PROFILES_DATA]: SetUserAppData exception {0}", e.Message);
1024 return false;
1025 }
1026 return true;
1027 }
1028 #endregion Integration
1029 }
1030} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs
new file mode 100644
index 0000000..9f9c9cf
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs
@@ -0,0 +1,522 @@
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.IO;
32using System.IO.Compression;
33using System.Reflection;
34using System.Security.Cryptography;
35using System.Text;
36using log4net;
37using MySql.Data.MySqlClient;
38using OpenMetaverse;
39using OpenSim.Framework;
40using OpenSim.Data;
41
42namespace OpenSim.Data.MySQL
43{
44 public class MySQLXAssetData : IXAssetDataPlugin
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 protected virtual Assembly Assembly
49 {
50 get { return GetType().Assembly; }
51 }
52
53 /// <summary>
54 /// Number of days that must pass before we update the access time on an asset when it has been fetched.
55 /// </summary>
56 private const int DaysBetweenAccessTimeUpdates = 30;
57
58 private bool m_enableCompression = false;
59 private string m_connectionString;
60
61 /// <summary>
62 /// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
63 /// </summary>
64 private HashAlgorithm hasher = new SHA256CryptoServiceProvider();
65
66 #region IPlugin Members
67
68 public string Version { get { return "1.0.0.0"; } }
69
70 /// <summary>
71 /// <para>Initialises Asset interface</para>
72 /// <para>
73 /// <list type="bullet">
74 /// <item>Loads and initialises the MySQL storage plugin.</item>
75 /// <item>Warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
76 /// <item>Check for migration</item>
77 /// </list>
78 /// </para>
79 /// </summary>
80 /// <param name="connect">connect string</param>
81 public void Initialise(string connect)
82 {
83 m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
84 m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
85 m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
86 m_log.ErrorFormat("[MYSQL XASSETDATA]: THIS PLUGIN IS STRICTLY EXPERIMENTAL.");
87 m_log.ErrorFormat("[MYSQL XASSETDATA]: DO NOT USE FOR ANY DATA THAT YOU DO NOT MIND LOSING.");
88 m_log.ErrorFormat("[MYSQL XASSETDATA]: DATABASE TABLES CAN CHANGE AT ANY TIME, CAUSING EXISTING DATA TO BE LOST.");
89 m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
90 m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
91 m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
92
93 m_connectionString = connect;
94
95 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
96 {
97 dbcon.Open();
98 Migration m = new Migration(dbcon, Assembly, "XAssetStore");
99 m.Update();
100 dbcon.Close();
101 }
102 }
103
104 public void Initialise()
105 {
106 throw new NotImplementedException();
107 }
108
109 public void Dispose() { }
110
111 /// <summary>
112 /// The name of this DB provider
113 /// </summary>
114 public string Name
115 {
116 get { return "MySQL XAsset storage engine"; }
117 }
118
119 #endregion
120
121 #region IAssetDataPlugin Members
122
123 /// <summary>
124 /// Fetch Asset <paramref name="assetID"/> from database
125 /// </summary>
126 /// <param name="assetID">Asset UUID to fetch</param>
127 /// <returns>Return the asset</returns>
128 /// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks>
129 public AssetBase GetAsset(UUID assetID)
130 {
131// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
132
133 AssetBase asset = null;
134 int accessTime = 0;
135
136 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
137 {
138 dbcon.Open();
139
140 using (MySqlCommand cmd = new MySqlCommand(
141 "SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID",
142 dbcon))
143 {
144 cmd.Parameters.AddWithValue("?ID", assetID.ToString());
145 try
146 {
147 using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
148 {
149 if (dbReader.Read())
150 {
151 asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
152 asset.Data = (byte[])dbReader["Data"];
153 asset.Description = (string)dbReader["Description"];
154
155 string local = dbReader["Local"].ToString();
156 if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
157 asset.Local = true;
158 else
159 asset.Local = false;
160
161 asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
162 asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
163 accessTime = (int)dbReader["AccessTime"];
164 }
165 }
166 }
167 catch (Exception e)
168 {
169 m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
170 }
171 }
172 dbcon.Close();
173 }
174
175 if(asset == null)
176 return asset;
177
178 if(accessTime > 0)
179 {
180 try
181 {
182 UpdateAccessTime(asset.Metadata, accessTime);
183 }
184 catch { }
185 }
186
187 if (m_enableCompression && asset.Data != null)
188 {
189 using(MemoryStream ms = new MemoryStream(asset.Data))
190 using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress))
191 {
192 using(MemoryStream outputStream = new MemoryStream())
193 {
194 decompressionStream.CopyTo(outputStream, int.MaxValue);
195// int compressedLength = asset.Data.Length;
196 asset.Data = outputStream.ToArray();
197 }
198// m_log.DebugFormat(
199// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
200// asset.ID, asset.Name, asset.Data.Length, compressedLength);
201 }
202 }
203 return asset;
204 }
205
206 /// <summary>
207 /// Create an asset in database, or update it if existing.
208 /// </summary>
209 /// <param name="asset">Asset UUID to create</param>
210 /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
211 public void StoreAsset(AssetBase asset)
212 {
213// m_log.DebugFormat("[XASSETS DB]: Storing asset {0} {1}", asset.Name, asset.ID);
214
215 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
216 {
217 dbcon.Open();
218
219 using (MySqlTransaction transaction = dbcon.BeginTransaction())
220 {
221 string assetName = asset.Name;
222 if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
223 {
224 assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
225 m_log.WarnFormat(
226 "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
227 asset.Name, asset.ID, asset.Name.Length, assetName.Length);
228 }
229
230 string assetDescription = asset.Description;
231 if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
232 {
233 assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
234 m_log.WarnFormat(
235 "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
236 asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
237 }
238
239 if (m_enableCompression)
240 {
241 MemoryStream outputStream = new MemoryStream();
242
243 using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
244 {
245// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
246 // We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
247 compressionStream.Close();
248 byte[] compressedData = outputStream.ToArray();
249 asset.Data = compressedData;
250 }
251 }
252
253 byte[] hash = hasher.ComputeHash(asset.Data);
254
255// m_log.DebugFormat(
256// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
257// asset.ID, asset.Name, hash, compressedData.Length);
258
259 try
260 {
261 using (MySqlCommand cmd =
262 new MySqlCommand(
263 "replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" +
264 "VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)",
265 dbcon))
266 {
267 // create unix epoch time
268 int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
269 cmd.Parameters.AddWithValue("?ID", asset.ID);
270 cmd.Parameters.AddWithValue("?Hash", hash);
271 cmd.Parameters.AddWithValue("?Name", assetName);
272 cmd.Parameters.AddWithValue("?Description", assetDescription);
273 cmd.Parameters.AddWithValue("?AssetType", asset.Type);
274 cmd.Parameters.AddWithValue("?Local", asset.Local);
275 cmd.Parameters.AddWithValue("?Temporary", asset.Temporary);
276 cmd.Parameters.AddWithValue("?CreateTime", now);
277 cmd.Parameters.AddWithValue("?AccessTime", now);
278 cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
279 cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags);
280 cmd.ExecuteNonQuery();
281 }
282 }
283 catch (Exception e)
284 {
285 m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
286 asset.FullID, asset.Name, e.Message);
287
288 transaction.Rollback();
289
290 return;
291 }
292
293 if (!ExistsData(dbcon, transaction, hash))
294 {
295 try
296 {
297 using (MySqlCommand cmd =
298 new MySqlCommand(
299 "INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)",
300 dbcon))
301 {
302 cmd.Parameters.AddWithValue("?Hash", hash);
303 cmd.Parameters.AddWithValue("?Data", asset.Data);
304 cmd.ExecuteNonQuery();
305 }
306 }
307 catch (Exception e)
308 {
309 m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
310 asset.FullID, asset.Name, e.Message);
311
312 transaction.Rollback();
313
314 return;
315 }
316 }
317
318 transaction.Commit();
319 }
320 dbcon.Close();
321 }
322 }
323
324 /// <summary>
325 /// Updates the access time of the asset if it was accessed above a given threshhold amount of time.
326 /// </summary>
327 /// <remarks>
328 /// This gives us some insight into assets which haven't ben accessed for a long period. This is only done
329 /// over the threshold time to avoid excessive database writes as assets are fetched.
330 /// </remarks>
331 /// <param name='asset'></param>
332 /// <param name='accessTime'></param>
333 private void UpdateAccessTime(AssetMetadata assetMetadata, int accessTime)
334 {
335 DateTime now = DateTime.UtcNow;
336
337 if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
338 return;
339
340 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
341 {
342 dbcon.Open();
343 MySqlCommand cmd =
344 new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon);
345
346 try
347 {
348 using (cmd)
349 {
350 // create unix epoch time
351 cmd.Parameters.AddWithValue("?ID", assetMetadata.ID);
352 cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now));
353 cmd.ExecuteNonQuery();
354 }
355 }
356 catch (Exception)
357 {
358 m_log.ErrorFormat(
359 "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
360 assetMetadata.ID, assetMetadata.Name);
361 }
362 dbcon.Close();
363 }
364 }
365
366 /// <summary>
367 /// We assume we already have the m_dbLock.
368 /// </summary>
369 /// TODO: need to actually use the transaction.
370 /// <param name="dbcon"></param>
371 /// <param name="transaction"></param>
372 /// <param name="hash"></param>
373 /// <returns></returns>
374 private bool ExistsData(MySqlConnection dbcon, MySqlTransaction transaction, byte[] hash)
375 {
376// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
377
378 bool exists = false;
379
380 using (MySqlCommand cmd = new MySqlCommand("SELECT Hash FROM XAssetsData WHERE Hash=?Hash", dbcon))
381 {
382 cmd.Parameters.AddWithValue("?Hash", hash);
383
384 try
385 {
386 using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
387 {
388 if (dbReader.Read())
389 {
390// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
391 exists = true;
392 }
393 }
394 }
395 catch (Exception e)
396 {
397 m_log.ErrorFormat(
398 "[XASSETS DB]: MySql failure in ExistsData fetching hash {0}. Exception {1}{2}",
399 hash, e.Message, e.StackTrace);
400 }
401 }
402
403 return exists;
404 }
405
406 /// <summary>
407 /// Check if the assets exist in the database.
408 /// </summary>
409 /// <param name="uuids">The asset UUID's</param>
410 /// <returns>For each asset: true if it exists, false otherwise</returns>
411 public bool[] AssetsExist(UUID[] uuids)
412 {
413 if (uuids.Length == 0)
414 return new bool[0];
415
416 HashSet<UUID> exists = new HashSet<UUID>();
417
418 string ids = "'" + string.Join("','", uuids) + "'";
419 string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
420
421 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
422 {
423 dbcon.Open();
424 using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
425 {
426 using (MySqlDataReader dbReader = cmd.ExecuteReader())
427 {
428 while (dbReader.Read())
429 {
430 UUID id = DBGuid.FromDB(dbReader["ID"]);
431 exists.Add(id);
432 }
433 }
434 }
435 }
436
437 bool[] results = new bool[uuids.Length];
438 for (int i = 0; i < uuids.Length; i++)
439 results[i] = exists.Contains(uuids[i]);
440 return results;
441 }
442
443
444 /// <summary>
445 /// Returns a list of AssetMetadata objects. The list is a subset of
446 /// the entire data set offset by <paramref name="start" /> containing
447 /// <paramref name="count" /> elements.
448 /// </summary>
449 /// <param name="start">The number of results to discard from the total data set.</param>
450 /// <param name="count">The number of rows the returned list should contain.</param>
451 /// <returns>A list of AssetMetadata objects.</returns>
452 public List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
453 {
454 List<AssetMetadata> retList = new List<AssetMetadata>(count);
455
456 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
457 {
458 dbcon.Open();
459 using(MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count",dbcon))
460 {
461 cmd.Parameters.AddWithValue("?start",start);
462 cmd.Parameters.AddWithValue("?count", count);
463
464 try
465 {
466 using (MySqlDataReader dbReader = cmd.ExecuteReader())
467 {
468 while (dbReader.Read())
469 {
470 AssetMetadata metadata = new AssetMetadata();
471 metadata.Name = (string)dbReader["Name"];
472 metadata.Description = (string)dbReader["Description"];
473 metadata.Type = (sbyte)dbReader["AssetType"];
474 metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
475 metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
476 metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
477 metadata.CreatorID = dbReader["CreatorID"].ToString();
478
479 // We'll ignore this for now - it appears unused!
480 // metadata.SHA1 = dbReader["hash"]);
481
482 UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
483
484 retList.Add(metadata);
485 }
486 }
487 }
488 catch (Exception e)
489 {
490 m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
491 }
492 }
493 dbcon.Close();
494 }
495
496 return retList;
497 }
498
499 public bool Delete(string id)
500 {
501// m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id);
502
503 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
504 {
505 dbcon.Open();
506
507 using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon))
508 {
509 cmd.Parameters.AddWithValue("?ID", id);
510 cmd.ExecuteNonQuery();
511 }
512 // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
513 // keep a reference count (?)
514 dbcon.Close();
515 }
516
517 return true;
518 }
519
520 #endregion
521 }
522}
diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
new file mode 100644
index 0000000..5019994
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
@@ -0,0 +1,339 @@
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.Linq;
32using System.Reflection;
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 Asset Server
42 /// </summary>
43 public class MySQLXInventoryData : IXInventoryData
44 {
45 private MySqlFolderHandler m_Folders;
46 private MySqlItemHandler m_Items;
47
48 public MySQLXInventoryData(string conn, string realm)
49 {
50 m_Folders = new MySqlFolderHandler(
51 conn, "inventoryfolders", "InventoryStore");
52 m_Items = new MySqlItemHandler(
53 conn, "inventoryitems", String.Empty);
54 }
55
56 public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
57 {
58 return m_Folders.Get(fields, vals);
59 }
60
61 public XInventoryItem[] GetItems(string[] fields, string[] vals)
62 {
63 return m_Items.Get(fields, vals);
64 }
65
66 public bool StoreFolder(XInventoryFolder folder)
67 {
68 if (folder.folderName.Length > 64)
69 folder.folderName = folder.folderName.Substring(0, 64);
70
71 return m_Folders.Store(folder);
72 }
73
74 public bool StoreItem(XInventoryItem item)
75 {
76 if (item.inventoryName.Length > 64)
77 item.inventoryName = item.inventoryName.Substring(0, 64);
78 if (item.inventoryDescription.Length > 128)
79 item.inventoryDescription = item.inventoryDescription.Substring(0, 128);
80
81 return m_Items.Store(item);
82 }
83
84 public bool DeleteFolders(string field, string val)
85 {
86 return m_Folders.Delete(field, val);
87 }
88
89 public bool DeleteFolders(string[] fields, string[] vals)
90 {
91 return m_Folders.Delete(fields, vals);
92 }
93
94 public bool DeleteItems(string field, string val)
95 {
96 return m_Items.Delete(field, val);
97 }
98
99 public bool DeleteItems(string[] fields, string[] vals)
100 {
101 return m_Items.Delete(fields, vals);
102 }
103
104 public bool MoveItem(string id, string newParent)
105 {
106 return m_Items.MoveItem(id, newParent);
107 }
108
109 public bool MoveFolder(string id, string newParent)
110 {
111 return m_Folders.MoveFolder(id, newParent);
112 }
113
114 public XInventoryItem[] GetActiveGestures(UUID principalID)
115 {
116 return m_Items.GetActiveGestures(principalID);
117 }
118
119 public int GetAssetPermissions(UUID principalID, UUID assetID)
120 {
121 return m_Items.GetAssetPermissions(principalID, assetID);
122 }
123 }
124
125 public class MySqlItemHandler : MySqlInventoryHandler<XInventoryItem>
126 {
127// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
128
129 public MySqlItemHandler(string c, string t, string m) :
130 base(c, t, m)
131 {
132 }
133
134 public override bool Delete(string field, string val)
135 {
136 XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val });
137 if (retrievedItems.Length == 0)
138 return false;
139
140 if (!base.Delete(field, val))
141 return false;
142
143 // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[])
144// IncrementFolderVersion(retrievedItems[0].parentFolderID);
145
146 return true;
147 }
148
149 public override bool Delete(string[] fields, string[] vals)
150 {
151 XInventoryItem[] retrievedItems = Get(fields, vals);
152 if (retrievedItems.Length == 0)
153 return false;
154
155 if (!base.Delete(fields, vals))
156 return false;
157
158 HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>();
159
160 Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID));
161
162 foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs)
163 IncrementFolderVersion(deletedItemFolderUUID);
164
165 return true;
166 }
167
168 public bool MoveItem(string id, string newParent)
169 {
170 XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
171 if (retrievedItems.Length == 0)
172 return false;
173
174 UUID oldParent = retrievedItems[0].parentFolderID;
175
176 using (MySqlCommand cmd = new MySqlCommand())
177 {
178 cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm);
179 cmd.Parameters.AddWithValue("?ParentFolderID", newParent);
180 cmd.Parameters.AddWithValue("?InventoryID", id);
181
182 if (ExecuteNonQuery(cmd) == 0)
183 return false;
184 }
185
186 IncrementFolderVersion(oldParent);
187 IncrementFolderVersion(newParent);
188
189 return true;
190 }
191
192 public XInventoryItem[] GetActiveGestures(UUID principalID)
193 {
194 using (MySqlCommand cmd = new MySqlCommand())
195 {
196// cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1", m_Realm);
197
198 cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1");
199
200 cmd.Parameters.AddWithValue("?uuid", principalID.ToString());
201 cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
202
203 return DoQuery(cmd);
204 }
205 }
206
207 public int GetAssetPermissions(UUID principalID, UUID assetID)
208 {
209 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
210 {
211 dbcon.Open();
212
213 using (MySqlCommand cmd = new MySqlCommand())
214 {
215 cmd.Connection = dbcon;
216
217// cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm);
218
219 cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID");
220
221 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
222 cmd.Parameters.AddWithValue("?AssetID", assetID.ToString());
223
224 using (IDataReader reader = cmd.ExecuteReader())
225 {
226
227 int perms = 0;
228
229 if (reader.Read())
230 {
231 perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
232 }
233
234 return perms;
235 }
236 }
237 }
238 }
239
240 public override bool Store(XInventoryItem item)
241 {
242 if (!base.Store(item))
243 return false;
244
245 IncrementFolderVersion(item.parentFolderID);
246
247 return true;
248 }
249 }
250
251 public class MySqlFolderHandler : MySqlInventoryHandler<XInventoryFolder>
252 {
253// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
254
255 public MySqlFolderHandler(string c, string t, string m) :
256 base(c, t, m)
257 {
258 }
259
260 public bool MoveFolder(string id, string newParentFolderID)
261 {
262 XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
263
264 if (folders.Length == 0)
265 return false;
266
267 UUID oldParentFolderUUID = folders[0].parentFolderID;
268
269 using (MySqlCommand cmd = new MySqlCommand())
270 {
271 cmd.CommandText
272 = String.Format(
273 "update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm);
274 cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID);
275 cmd.Parameters.AddWithValue("?folderID", id);
276
277 if (ExecuteNonQuery(cmd) == 0)
278 return false;
279 }
280
281 IncrementFolderVersion(oldParentFolderUUID);
282 IncrementFolderVersion(newParentFolderID);
283
284 return true;
285 }
286
287 public override bool Store(XInventoryFolder folder)
288 {
289 if (!base.Store(folder))
290 return false;
291
292 IncrementFolderVersion(folder.parentFolderID);
293
294 return true;
295 }
296 }
297
298 public class MySqlInventoryHandler<T> : MySQLGenericTableHandler<T> where T: class, new()
299 {
300 public MySqlInventoryHandler(string c, string t, string m) : base(c, t, m) {}
301
302 protected bool IncrementFolderVersion(UUID folderID)
303 {
304 return IncrementFolderVersion(folderID.ToString());
305 }
306
307 protected bool IncrementFolderVersion(string folderID)
308 {
309// m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID);
310// Util.PrintCallStack();
311
312 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
313 {
314 dbcon.Open();
315
316 using (MySqlCommand cmd = new MySqlCommand())
317 {
318 cmd.Connection = dbcon;
319
320 cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
321 cmd.Parameters.AddWithValue("?folderID", folderID);
322
323 try
324 {
325 cmd.ExecuteNonQuery();
326 }
327 catch (Exception)
328 {
329 return false;
330 }
331 }
332
333 dbcon.Close();
334 }
335
336 return true;
337 }
338 }
339} \ No newline at end of file
diff --git a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6507a37
--- /dev/null
+++ b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs
@@ -0,0 +1,65 @@
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.Reflection;
29using System.Runtime.InteropServices;
30
31// General information about an assembly is controlled through the following
32// set of attributes. Change these attribute values to modify the information
33// associated with an assembly.
34
35[assembly : AssemblyTitle("OpenSim.Data.MySQL")]
36[assembly : AssemblyDescription("")]
37[assembly : AssemblyConfiguration("")]
38[assembly : AssemblyCompany("http://opensimulator.org")]
39[assembly : AssemblyProduct("OpenSim.Data.MySQL")]
40[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
41[assembly : AssemblyTrademark("")]
42[assembly : AssemblyCulture("")]
43
44// Setting ComVisible to false makes the types in this assembly not visible
45// to COM components. If you need to access a type in this assembly from
46// COM, set the ComVisible attribute to true on that type.
47
48[assembly : ComVisible(false)]
49
50// The following GUID is for the ID of the typelib if this project is exposed to COM
51
52[assembly : Guid("e49826b2-dcef-41be-a5bd-596733fa3304")]
53
54// Version information for an assembly consists of the following four values:
55//
56// Major Version
57// Minor Version
58// Build Number
59// Revision
60//
61// You can specify all the values or you can default the Revision and Build Numbers
62// by using the '*' as shown below:
63
64[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
65
diff --git a/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations
new file mode 100644
index 0000000..d41ae66
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations
@@ -0,0 +1,18 @@
1:VERSION 1 # -------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `AgentPrefs` (
6 `PrincipalID` CHAR(36) NOT NULL,
7 `AccessPrefs` CHAR(2) NOT NULL DEFAULT 'M',
8 `HoverHeight` DOUBLE(30, 27) NOT NULL DEFAULT 0,
9 `Language` CHAR(5) NOT NULL DEFAULT 'en-us',
10 `LanguageIsPublic` BOOLEAN NOT NULL DEFAULT 1,
11 `PermEveryone` INT(6) NOT NULL DEFAULT 0,
12 `PermGroup` INT(6) NOT NULL DEFAULT 0,
13 `PermNextOwner` INT(6) NOT NULL DEFAULT 532480,
14 UNIQUE KEY `PrincipalID` (`PrincipalID`),
15 PRIMARY KEY(`PrincipalID`)
16) ENGINE=MyISAM DEFAULT CHARSET=utf8;
17
18COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/AssetStore.migrations b/OpenSim/Data/MySQL/Resources/AssetStore.migrations
new file mode 100644
index 0000000..07f521b
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/AssetStore.migrations
@@ -0,0 +1,21 @@
1# -----------------
2:VERSION 10
3
4BEGIN;
5
6CREATE TABLE IF NOT EXISTS `assets` (
7 `name` varchar(64) NOT NULL,
8 `description` varchar(64) NOT NULL,
9 `assetType` tinyint(4) NOT NULL,
10 `local` tinyint(1) NOT NULL,
11 `temporary` tinyint(1) NOT NULL,
12 `data` longblob NOT NULL,
13 `id` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
14 `create_time` int(11) DEFAULT '0',
15 `access_time` int(11) DEFAULT '0',
16 `asset_flags` int(11) NOT NULL DEFAULT '0',
17 `CreatorID` varchar(128) NOT NULL DEFAULT '',
18 PRIMARY KEY (`id`)
19) ENGINE=MyISAM DEFAULT CHARSET=utf8;
20
21COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/AuthStore.migrations b/OpenSim/Data/MySQL/Resources/AuthStore.migrations
new file mode 100644
index 0000000..8d24fbd
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/AuthStore.migrations
@@ -0,0 +1,24 @@
1:VERSION 4 # -------------------------------
2
3begin;
4
5CREATE TABLE IF NOT EXISTS `auth` (
6 `UUID` char(36) NOT NULL,
7 `passwordHash` char(32) NOT NULL DEFAULT '',
8 `passwordSalt` char(32) NOT NULL DEFAULT '',
9 `webLoginKey` varchar(255) NOT NULL DEFAULT '',
10 `accountType` varchar(32) NOT NULL DEFAULT 'UserAccount',
11 PRIMARY KEY (`UUID`)
12) ENGINE=MyISAM DEFAULT CHARSET=utf8;
13
14CREATE TABLE IF NOT EXISTS `tokens` (
15 `UUID` char(36) NOT NULL,
16 `token` varchar(255) NOT NULL,
17 `validity` datetime NOT NULL,
18 UNIQUE KEY `uuid_token` (`UUID`,`token`),
19 KEY `UUID` (`UUID`),
20 KEY `token` (`token`),
21 KEY `validity` (`validity`)
22) ENGINE=MyISAM DEFAULT CHARSET=utf8;
23
24COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/Avatar.migrations b/OpenSim/Data/MySQL/Resources/Avatar.migrations
new file mode 100644
index 0000000..66f75b2
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/Avatar.migrations
@@ -0,0 +1,13 @@
1:VERSION 3
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `Avatars` (
6 `PrincipalID` char(36) NOT NULL,
7 `Name` varchar(32) NOT NULL,
8 `Value` text,
9 PRIMARY KEY (`PrincipalID`,`Name`),
10 KEY `PrincipalID` (`PrincipalID`)
11) ENGINE=MyISAM DEFAULT CHARSET=utf8;
12
13COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/EstateStore.migrations b/OpenSim/Data/MySQL/Resources/EstateStore.migrations
new file mode 100644
index 0000000..9c1ed83
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/EstateStore.migrations
@@ -0,0 +1,71 @@
1:VERSION 34
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `estate_groups` (
6 `EstateID` int(10) unsigned NOT NULL,
7 `uuid` char(36) NOT NULL,
8 KEY `EstateID` (`EstateID`)
9) ENGINE=MyISAM DEFAULT CHARSET=utf8;
10
11CREATE TABLE IF NOT EXISTS `estate_managers` (
12 `EstateID` int(10) unsigned NOT NULL,
13 `uuid` char(36) NOT NULL,
14 KEY `EstateID` (`EstateID`)
15) ENGINE=MyISAM DEFAULT CHARSET=utf8;
16
17CREATE TABLE IF NOT EXISTS `estate_map` (
18 `RegionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
19 `EstateID` int(11) NOT NULL,
20 PRIMARY KEY (`RegionID`),
21 KEY `EstateID` (`EstateID`)
22) ENGINE=MyISAM DEFAULT CHARSET=utf8;
23
24CREATE TABLE IF NOT EXISTS `estate_settings` (
25 `EstateID` int(10) unsigned NOT NULL AUTO_INCREMENT,
26 `EstateName` varchar(64) DEFAULT NULL,
27 `AbuseEmailToEstateOwner` tinyint(4) NOT NULL,
28 `DenyAnonymous` tinyint(4) NOT NULL,
29 `ResetHomeOnTeleport` tinyint(4) NOT NULL,
30 `FixedSun` tinyint(4) NOT NULL,
31 `DenyTransacted` tinyint(4) NOT NULL,
32 `BlockDwell` tinyint(4) NOT NULL,
33 `DenyIdentified` tinyint(4) NOT NULL,
34 `AllowVoice` tinyint(4) NOT NULL,
35 `UseGlobalTime` tinyint(4) NOT NULL,
36 `PricePerMeter` int(11) NOT NULL,
37 `TaxFree` tinyint(4) NOT NULL,
38 `AllowDirectTeleport` tinyint(4) NOT NULL,
39 `RedirectGridX` int(11) NOT NULL,
40 `RedirectGridY` int(11) NOT NULL,
41 `ParentEstateID` int(10) unsigned NOT NULL,
42 `SunPosition` double NOT NULL,
43 `EstateSkipScripts` tinyint(4) NOT NULL,
44 `BillableFactor` float NOT NULL,
45 `PublicAccess` tinyint(4) NOT NULL,
46 `AbuseEmail` varchar(255) NOT NULL,
47 `EstateOwner` varchar(36) NOT NULL,
48 `DenyMinors` tinyint(4) NOT NULL,
49 `AllowLandmark` tinyint(4) NOT NULL DEFAULT '1',
50 `AllowParcelChanges` tinyint(4) NOT NULL DEFAULT '1',
51 `AllowSetHome` tinyint(4) NOT NULL DEFAULT '1',
52 PRIMARY KEY (`EstateID`)
53) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=utf8;
54
55CREATE TABLE IF NOT EXISTS `estate_users` (
56 `EstateID` int(10) unsigned NOT NULL,
57 `uuid` char(36) NOT NULL,
58 KEY `EstateID` (`EstateID`)
59) ENGINE=MyISAM DEFAULT CHARSET=utf8;
60
61CREATE TABLE IF NOT EXISTS `estateban` (
62 `EstateID` int(10) unsigned NOT NULL,
63 `bannedUUID` varchar(36) NOT NULL,
64 `bannedIp` varchar(16) NOT NULL,
65 `bannedIpHostMask` varchar(16) NOT NULL,
66 `bannedNameMask` varchar(64) DEFAULT NULL,
67 KEY `estateban_EstateID` (`EstateID`)
68) ENGINE=MyISAM DEFAULT CHARSET=utf8;
69
70COMMIT;
71
diff --git a/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations
new file mode 100644
index 0000000..3f65d9e
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations
@@ -0,0 +1,18 @@
1# -----------------
2:VERSION 1
3
4BEGIN;
5
6CREATE TABLE IF NOT EXISTS `fsassets` (
7 `id` char(36) NOT NULL,
8 `name` varchar(64) NOT NULL DEFAULT '',
9 `description` varchar(64) NOT NULL DEFAULT '',
10 `type` int(11) NOT NULL,
11 `hash` char(80) NOT NULL,
12 `create_time` int(11) NOT NULL DEFAULT '0',
13 `access_time` int(11) NOT NULL DEFAULT '0',
14 `asset_flags` int(11) NOT NULL DEFAULT '0',
15 PRIMARY KEY (`id`)
16) ENGINE=MyISAM DEFAULT CHARSET=utf8;
17
18COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
new file mode 100644
index 0000000..7dc7607
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
@@ -0,0 +1,14 @@
1:VERSION 4 # -------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `Friends` (
6 `PrincipalID` varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
7 `Friend` varchar(255) NOT NULL,
8 `Flags` varchar(16) NOT NULL DEFAULT '0',
9 `Offered` varchar(32) NOT NULL DEFAULT '0',
10 PRIMARY KEY (`PrincipalID`(36),`Friend`(36)),
11 KEY `PrincipalID` (`PrincipalID`)
12) ENGINE=MyISAM DEFAULT CHARSET=utf8;
13
14COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/GridStore.migrations b/OpenSim/Data/MySQL/Resources/GridStore.migrations
new file mode 100644
index 0000000..4116235
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/GridStore.migrations
@@ -0,0 +1,52 @@
1:VERSION 10
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `regions` (
6 `uuid` varchar(36) NOT NULL,
7 `regionHandle` bigint(20) unsigned NOT NULL,
8 `regionName` varchar(128) DEFAULT NULL,
9 `regionRecvKey` varchar(128) DEFAULT NULL,
10 `regionSendKey` varchar(128) DEFAULT NULL,
11 `regionSecret` varchar(128) DEFAULT NULL,
12 `regionDataURI` varchar(255) DEFAULT NULL,
13 `serverIP` varchar(64) DEFAULT NULL,
14 `serverPort` int(10) unsigned DEFAULT NULL,
15 `serverURI` varchar(255) DEFAULT NULL,
16 `locX` int(10) unsigned DEFAULT NULL,
17 `locY` int(10) unsigned DEFAULT NULL,
18 `locZ` int(10) unsigned DEFAULT NULL,
19 `eastOverrideHandle` bigint(20) unsigned DEFAULT NULL,
20 `westOverrideHandle` bigint(20) unsigned DEFAULT NULL,
21 `southOverrideHandle` bigint(20) unsigned DEFAULT NULL,
22 `northOverrideHandle` bigint(20) unsigned DEFAULT NULL,
23 `regionAssetURI` varchar(255) DEFAULT NULL,
24 `regionAssetRecvKey` varchar(128) DEFAULT NULL,
25 `regionAssetSendKey` varchar(128) DEFAULT NULL,
26 `regionUserURI` varchar(255) DEFAULT NULL,
27 `regionUserRecvKey` varchar(128) DEFAULT NULL,
28 `regionUserSendKey` varchar(128) DEFAULT NULL,
29 `regionMapTexture` varchar(36) DEFAULT NULL,
30 `serverHttpPort` int(10) DEFAULT NULL,
31 `serverRemotingPort` int(10) DEFAULT NULL,
32 `owner_uuid` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
33 `originUUID` varchar(36) DEFAULT NULL,
34 `access` int(10) unsigned DEFAULT '1',
35 `ScopeID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
36 `sizeX` int(11) NOT NULL DEFAULT '0',
37 `sizeY` int(11) NOT NULL DEFAULT '0',
38 `flags` int(11) NOT NULL DEFAULT '0',
39 `last_seen` int(11) NOT NULL DEFAULT '0',
40 `PrincipalID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
41 `Token` varchar(255) NOT NULL,
42 `parcelMapTexture` varchar(36) DEFAULT NULL,
43 PRIMARY KEY (`uuid`),
44 KEY `regionName` (`regionName`),
45 KEY `regionHandle` (`regionHandle`),
46 KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`),
47 KEY `ScopeID` (`ScopeID`),
48 KEY `flags` (`flags`)
49) ENGINE=MyISAM DEFAULT CHARSET=utf8;
50
51COMMIT;
52
diff --git a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations
new file mode 100644
index 0000000..dd73974
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations
@@ -0,0 +1,19 @@
1:VERSION 1 # --------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `GridUser` (
6 `UserID` VARCHAR(255) NOT NULL,
7 `HomeRegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 `HomePosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
9 `HomeLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
10 `LastRegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
11 `LastPosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
12 `LastLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
13 `Online` CHAR(5) NOT NULL DEFAULT 'false',
14 `Login` CHAR(16) NOT NULL DEFAULT '0',
15 `Logout` CHAR(16) NOT NULL DEFAULT '0',
16 PRIMARY KEY (`UserID`)
17) ENGINE=MyISAM DEFAULT CHARSET=utf8;
18
19COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations
new file mode 100644
index 0000000..ed1fede
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations
@@ -0,0 +1,17 @@
1:VERSION 1 # --------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `hg_traveling_data` (
6 `SessionID` VARCHAR(36) NOT NULL,
7 `UserID` VARCHAR(36) NOT NULL,
8 `GridExternalName` VARCHAR(255) NOT NULL DEFAULT '',
9 `ServiceToken` VARCHAR(255) NOT NULL DEFAULT '',
10 `ClientIPAddress` VARCHAR(16) NOT NULL DEFAULT '',
11 `MyIPAddress` VARCHAR(16) NOT NULL DEFAULT '',
12 `TMStamp` timestamp NOT NULL,
13 PRIMARY KEY (`SessionID`),
14 KEY (`UserID`)
15) ENGINE=MyISAM DEFAULT CHARSET=utf8;
16
17COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/IM_Store.migrations b/OpenSim/Data/MySQL/Resources/IM_Store.migrations
new file mode 100644
index 0000000..e271fcc
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/IM_Store.migrations
@@ -0,0 +1,16 @@
1:VERSION 5 # --------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `im_offline` (
6 `ID` mediumint(9) NOT NULL AUTO_INCREMENT,
7 `PrincipalID` char(36) NOT NULL DEFAULT '',
8 `FromID` char(36) NOT NULL DEFAULT '',
9 `Message` text NOT NULL,
10 `TMStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
11 PRIMARY KEY (`ID`),
12 KEY `PrincipalID` (`PrincipalID`),
13 KEY `FromID` (`FromID`)
14) ENGINE=MyISAM DEFAULT CHARSET=utf8;
15
16COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/InventoryStore.migrations b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations
new file mode 100644
index 0000000..7283e41
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations
@@ -0,0 +1,42 @@
1:VERSION 7 # ------------
2BEGIN;
3
4CREATE TABLE IF NOT EXISTS `inventoryitems` (
5 `assetID` varchar(36) DEFAULT NULL,
6 `assetType` int(11) DEFAULT NULL,
7 `inventoryName` varchar(64) DEFAULT NULL,
8 `inventoryDescription` varchar(128) DEFAULT NULL,
9 `inventoryNextPermissions` int(10) unsigned DEFAULT NULL,
10 `inventoryCurrentPermissions` int(10) unsigned DEFAULT NULL,
11 `invType` int(11) DEFAULT NULL,
12 `creatorID` varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
13 `inventoryBasePermissions` int(10) unsigned NOT NULL DEFAULT '0',
14 `inventoryEveryOnePermissions` int(10) unsigned NOT NULL DEFAULT '0',
15 `salePrice` int(11) NOT NULL DEFAULT '0',
16 `saleType` tinyint(4) NOT NULL DEFAULT '0',
17 `creationDate` int(11) NOT NULL DEFAULT '0',
18 `groupID` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
19 `groupOwned` tinyint(4) NOT NULL DEFAULT '0',
20 `flags` int(11) unsigned NOT NULL DEFAULT '0',
21 `inventoryID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
22 `avatarID` char(36) DEFAULT NULL,
23 `parentFolderID` char(36) DEFAULT NULL,
24 `inventoryGroupPermissions` int(10) unsigned NOT NULL DEFAULT '0',
25 PRIMARY KEY (`inventoryID`),
26 KEY `inventoryitems_avatarid` (`avatarID`),
27 KEY `inventoryitems_parentFolderid` (`parentFolderID`)
28) ENGINE=MyISAM DEFAULT CHARSET=utf8;
29
30CREATE TABLE IF NOT EXISTS `inventoryfolders` (
31 `folderName` varchar(64) DEFAULT NULL,
32 `type` smallint(6) NOT NULL DEFAULT '0',
33 `version` int(11) NOT NULL DEFAULT '0',
34 `folderID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
35 `agentID` char(36) DEFAULT NULL,
36 `parentFolderID` char(36) DEFAULT NULL,
37 PRIMARY KEY (`folderID`),
38 KEY `inventoryfolders_agentid` (`agentID`),
39 KEY `inventoryfolders_parentFolderid` (`parentFolderID`)
40) ENGINE=MyISAM DEFAULT CHARSET=utf8;
41
42COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/LogStore.migrations b/OpenSim/Data/MySQL/Resources/LogStore.migrations
new file mode 100644
index 0000000..f2990cc
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/LogStore.migrations
@@ -0,0 +1,13 @@
1
2:VERSION 1
3
4CREATE TABLE IF NOT EXISTS `logs` (
5 `logID` int(10) unsigned NOT NULL auto_increment,
6 `target` varchar(36) default NULL,
7 `server` varchar(64) default NULL,
8 `method` varchar(64) default NULL,
9 `arguments` varchar(255) default NULL,
10 `priority` int(11) default NULL,
11 `message` text,
12 PRIMARY KEY (`logID`)
13) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --git a/OpenSim/Data/MySQL/Resources/MuteListStore.migrations b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations
new file mode 100644
index 0000000..164dc51
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations
@@ -0,0 +1,16 @@
1:VERSION 1
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `MuteList` (
6 `AgentID` char(36) NOT NULL,
7 `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 `MuteName` varchar(64) NOT NULL DEFAULT '',
9 `MuteType` int(11) NOT NULL DEFAULT '1',
10 `MuteFlags` int(11) NOT NULL DEFAULT '0',
11 `Stamp` int(11) NOT NULL,
12 UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`),
13 KEY `AgentID` (`AgentID`)
14) ENGINE=MyISAM DEFAULT CHARSET=utf8;
15
16COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations
new file mode 100644
index 0000000..4d14b9d
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/Presence.migrations
@@ -0,0 +1,16 @@
1:VERSION 4 # --------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `Presence` (
6 `UserID` varchar(255) NOT NULL,
7 `RegionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 `SessionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
9 `SecureSessionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
10 `LastSeen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
11 UNIQUE KEY `SessionID` (`SessionID`),
12 KEY `UserID` (`UserID`),
13 KEY `RegionID` (`RegionID`)
14) ENGINE=MyISAM DEFAULT CHARSET=utf8;
15
16COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
new file mode 100644
index 0000000..fb7862a
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
@@ -0,0 +1,469 @@
1
2:VERSION 51 #---------------------
3
4BEGIN;
5
6CREATE TABLE IF NOT EXISTS `prims` (
7 `CreationDate` int(11) DEFAULT NULL,
8 `Name` varchar(255) DEFAULT NULL,
9 `Text` varchar(255) DEFAULT NULL,
10 `Description` varchar(255) DEFAULT NULL,
11 `SitName` varchar(255) DEFAULT NULL,
12 `TouchName` varchar(255) DEFAULT NULL,
13 `ObjectFlags` int(11) DEFAULT NULL,
14 `OwnerMask` int(11) DEFAULT NULL,
15 `NextOwnerMask` int(11) DEFAULT NULL,
16 `GroupMask` int(11) DEFAULT NULL,
17 `EveryoneMask` int(11) DEFAULT NULL,
18 `BaseMask` int(11) DEFAULT NULL,
19 `PositionX` double DEFAULT NULL,
20 `PositionY` double DEFAULT NULL,
21 `PositionZ` double DEFAULT NULL,
22 `GroupPositionX` double DEFAULT NULL,
23 `GroupPositionY` double DEFAULT NULL,
24 `GroupPositionZ` double DEFAULT NULL,
25 `VelocityX` double DEFAULT NULL,
26 `VelocityY` double DEFAULT NULL,
27 `VelocityZ` double DEFAULT NULL,
28 `AngularVelocityX` double DEFAULT NULL,
29 `AngularVelocityY` double DEFAULT NULL,
30 `AngularVelocityZ` double DEFAULT NULL,
31 `AccelerationX` double DEFAULT NULL,
32 `AccelerationY` double DEFAULT NULL,
33 `AccelerationZ` double DEFAULT NULL,
34 `RotationX` double DEFAULT NULL,
35 `RotationY` double DEFAULT NULL,
36 `RotationZ` double DEFAULT NULL,
37 `RotationW` double DEFAULT NULL,
38 `SitTargetOffsetX` double DEFAULT NULL,
39 `SitTargetOffsetY` double DEFAULT NULL,
40 `SitTargetOffsetZ` double DEFAULT NULL,
41 `SitTargetOrientW` double DEFAULT NULL,
42 `SitTargetOrientX` double DEFAULT NULL,
43 `SitTargetOrientY` double DEFAULT NULL,
44 `SitTargetOrientZ` double DEFAULT NULL,
45 `UUID` char(36) NOT NULL DEFAULT '',
46 `RegionUUID` char(36) DEFAULT NULL,
47 `CreatorID` varchar(255) NOT NULL DEFAULT '',
48 `OwnerID` char(36) DEFAULT NULL,
49 `GroupID` char(36) DEFAULT NULL,
50 `LastOwnerID` char(36) DEFAULT NULL,
51 `SceneGroupID` char(36) DEFAULT NULL,
52 `PayPrice` int(11) NOT NULL DEFAULT '0',
53 `PayButton1` int(11) NOT NULL DEFAULT '0',
54 `PayButton2` int(11) NOT NULL DEFAULT '0',
55 `PayButton3` int(11) NOT NULL DEFAULT '0',
56 `PayButton4` int(11) NOT NULL DEFAULT '0',
57 `LoopedSound` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
58 `LoopedSoundGain` double NOT NULL DEFAULT '0',
59 `TextureAnimation` blob,
60 `OmegaX` double NOT NULL DEFAULT '0',
61 `OmegaY` double NOT NULL DEFAULT '0',
62 `OmegaZ` double NOT NULL DEFAULT '0',
63 `CameraEyeOffsetX` double NOT NULL DEFAULT '0',
64 `CameraEyeOffsetY` double NOT NULL DEFAULT '0',
65 `CameraEyeOffsetZ` double NOT NULL DEFAULT '0',
66 `CameraAtOffsetX` double NOT NULL DEFAULT '0',
67 `CameraAtOffsetY` double NOT NULL DEFAULT '0',
68 `CameraAtOffsetZ` double NOT NULL DEFAULT '0',
69 `ForceMouselook` tinyint(4) NOT NULL DEFAULT '0',
70 `ScriptAccessPin` int(11) NOT NULL DEFAULT '0',
71 `AllowedDrop` tinyint(4) NOT NULL DEFAULT '0',
72 `DieAtEdge` tinyint(4) NOT NULL DEFAULT '0',
73 `SalePrice` int(11) NOT NULL DEFAULT '10',
74 `SaleType` tinyint(4) NOT NULL DEFAULT '0',
75 `ColorR` int(11) NOT NULL DEFAULT '0',
76 `ColorG` int(11) NOT NULL DEFAULT '0',
77 `ColorB` int(11) NOT NULL DEFAULT '0',
78 `ColorA` int(11) NOT NULL DEFAULT '0',
79 `ParticleSystem` blob,
80 `ClickAction` tinyint(4) NOT NULL DEFAULT '0',
81 `Material` tinyint(4) NOT NULL DEFAULT '3',
82 `CollisionSound` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
83 `CollisionSoundVolume` double NOT NULL DEFAULT '0',
84 `LinkNumber` int(11) NOT NULL DEFAULT '0',
85 `PassTouches` tinyint(4) NOT NULL DEFAULT '0',
86 `MediaURL` varchar(255) DEFAULT NULL,
87 `DynAttrs` text,
88 `PhysicsShapeType` tinyint(4) NOT NULL DEFAULT '0',
89 `Density` double NOT NULL DEFAULT '1000',
90 `GravityModifier` double NOT NULL DEFAULT '1',
91 `Friction` double NOT NULL DEFAULT '0.6',
92 `Restitution` double NOT NULL DEFAULT '0.5',
93 `KeyframeMotion` blob,
94 `AttachedPosX` double DEFAULT '0',
95 `AttachedPosY` double DEFAULT '0',
96 `AttachedPosZ` double DEFAULT '0',
97 PRIMARY KEY (`UUID`),
98 KEY `prims_regionuuid` (`RegionUUID`),
99 KEY `prims_scenegroupid` (`SceneGroupID`)
100) ENGINE=MyISAM DEFAULT CHARSET=latin1;
101
102CREATE TABLE IF NOT EXISTS `primshapes` (
103 `Shape` int(11) DEFAULT NULL,
104 `ScaleX` double NOT NULL DEFAULT '0',
105 `ScaleY` double NOT NULL DEFAULT '0',
106 `ScaleZ` double NOT NULL DEFAULT '0',
107 `PCode` int(11) DEFAULT NULL,
108 `PathBegin` int(11) DEFAULT NULL,
109 `PathEnd` int(11) DEFAULT NULL,
110 `PathScaleX` int(11) DEFAULT NULL,
111 `PathScaleY` int(11) DEFAULT NULL,
112 `PathShearX` int(11) DEFAULT NULL,
113 `PathShearY` int(11) DEFAULT NULL,
114 `PathSkew` int(11) DEFAULT NULL,
115 `PathCurve` int(11) DEFAULT NULL,
116 `PathRadiusOffset` int(11) DEFAULT NULL,
117 `PathRevolutions` int(11) DEFAULT NULL,
118 `PathTaperX` int(11) DEFAULT NULL,
119 `PathTaperY` int(11) DEFAULT NULL,
120 `PathTwist` int(11) DEFAULT NULL,
121 `PathTwistBegin` int(11) DEFAULT NULL,
122 `ProfileBegin` int(11) DEFAULT NULL,
123 `ProfileEnd` int(11) DEFAULT NULL,
124 `ProfileCurve` int(11) DEFAULT NULL,
125 `ProfileHollow` int(11) DEFAULT NULL,
126 `State` int(11) DEFAULT NULL,
127 `Texture` longblob,
128 `ExtraParams` longblob,
129 `UUID` char(36) NOT NULL DEFAULT '',
130 `Media` text,
131 `LastAttachPoint` int(4) NOT NULL DEFAULT '0',
132 PRIMARY KEY (`UUID`)
133) ENGINE=MyISAM DEFAULT CHARSET=latin1;
134
135CREATE TABLE IF NOT EXISTS `primitems` (
136 `invType` int(11) DEFAULT NULL,
137 `assetType` int(11) DEFAULT NULL,
138 `name` varchar(255) DEFAULT NULL,
139 `description` varchar(255) DEFAULT NULL,
140 `creationDate` bigint(20) DEFAULT NULL,
141 `nextPermissions` int(11) DEFAULT NULL,
142 `currentPermissions` int(11) DEFAULT NULL,
143 `basePermissions` int(11) DEFAULT NULL,
144 `everyonePermissions` int(11) DEFAULT NULL,
145 `groupPermissions` int(11) DEFAULT NULL,
146 `flags` int(11) NOT NULL DEFAULT '0',
147 `itemID` char(36) NOT NULL DEFAULT '',
148 `primID` char(36) DEFAULT NULL,
149 `assetID` char(36) DEFAULT NULL,
150 `parentFolderID` char(36) DEFAULT NULL,
151 `CreatorID` varchar(255) NOT NULL DEFAULT '',
152 `ownerID` char(36) DEFAULT NULL,
153 `groupID` char(36) DEFAULT NULL,
154 `lastOwnerID` char(36) DEFAULT NULL,
155 PRIMARY KEY (`itemID`),
156 KEY `primitems_primid` (`primID`)
157) ENGINE=MyISAM DEFAULT CHARSET=latin1;
158
159CREATE TABLE IF NOT EXISTS `terrain` (
160 `RegionUUID` varchar(255) DEFAULT NULL,
161 `Revision` int(11) DEFAULT NULL,
162 `Heightfield` longblob
163) ENGINE=MyISAM DEFAULT CHARSET=latin1;
164
165CREATE TABLE IF NOT EXISTS `land` (
166 `UUID` varchar(255) NOT NULL,
167 `RegionUUID` varchar(255) DEFAULT NULL,
168 `LocalLandID` int(11) DEFAULT NULL,
169 `Bitmap` longblob,
170 `Name` varchar(255) DEFAULT NULL,
171 `Description` varchar(255) DEFAULT NULL,
172 `OwnerUUID` varchar(255) DEFAULT NULL,
173 `IsGroupOwned` int(11) DEFAULT NULL,
174 `Area` int(11) DEFAULT NULL,
175 `AuctionID` int(11) DEFAULT NULL,
176 `Category` int(11) DEFAULT NULL,
177 `ClaimDate` int(11) DEFAULT NULL,
178 `ClaimPrice` int(11) DEFAULT NULL,
179 `GroupUUID` varchar(255) DEFAULT NULL,
180 `SalePrice` int(11) DEFAULT NULL,
181 `LandStatus` int(11) DEFAULT NULL,
182 `LandFlags` int(10) unsigned DEFAULT NULL,
183 `LandingType` int(11) DEFAULT NULL,
184 `MediaAutoScale` int(11) DEFAULT NULL,
185 `MediaTextureUUID` varchar(255) DEFAULT NULL,
186 `MediaURL` varchar(255) DEFAULT NULL,
187 `MusicURL` varchar(255) DEFAULT NULL,
188 `PassHours` float DEFAULT NULL,
189 `PassPrice` int(11) DEFAULT NULL,
190 `SnapshotUUID` varchar(255) DEFAULT NULL,
191 `UserLocationX` float DEFAULT NULL,
192 `UserLocationY` float DEFAULT NULL,
193 `UserLocationZ` float DEFAULT NULL,
194 `UserLookAtX` float DEFAULT NULL,
195 `UserLookAtY` float DEFAULT NULL,
196 `UserLookAtZ` float DEFAULT NULL,
197 `AuthbuyerID` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
198 `OtherCleanTime` int(11) NOT NULL DEFAULT '0',
199 `Dwell` int(11) NOT NULL DEFAULT '0',
200 `MediaType` varchar(32) NOT NULL DEFAULT 'none/none',
201 `MediaDescription` varchar(255) NOT NULL DEFAULT '',
202 `MediaSize` varchar(16) NOT NULL DEFAULT '0,0',
203 `MediaLoop` tinyint(1) NOT NULL DEFAULT '0',
204 `ObscureMusic` tinyint(1) NOT NULL DEFAULT '0',
205 `ObscureMedia` tinyint(1) NOT NULL DEFAULT '0',
206 PRIMARY KEY (`UUID`)
207) ENGINE=MyISAM DEFAULT CHARSET=utf8;
208
209CREATE TABLE IF NOT EXISTS `landaccesslist` (
210 `LandUUID` varchar(255) DEFAULT NULL,
211 `AccessUUID` varchar(255) DEFAULT NULL,
212 `Flags` int(11) DEFAULT NULL,
213 `Expires` int(11) NOT NULL DEFAULT '0'
214) ENGINE=MyISAM DEFAULT CHARSET=latin1;
215
216CREATE TABLE IF NOT EXISTS `regionban` (
217 `regionUUID` varchar(36) NOT NULL,
218 `bannedUUID` varchar(36) NOT NULL,
219 `bannedIp` varchar(16) NOT NULL,
220 `bannedIpHostMask` varchar(16) NOT NULL
221) ENGINE=MyISAM DEFAULT CHARSET=utf8;
222
223CREATE TABLE IF NOT EXISTS `regionsettings` (
224 `regionUUID` char(36) NOT NULL,
225 `block_terraform` int(11) NOT NULL,
226 `block_fly` int(11) NOT NULL,
227 `allow_damage` int(11) NOT NULL,
228 `restrict_pushing` int(11) NOT NULL,
229 `allow_land_resell` int(11) NOT NULL,
230 `allow_land_join_divide` int(11) NOT NULL,
231 `block_show_in_search` int(11) NOT NULL,
232 `agent_limit` int(11) NOT NULL,
233 `object_bonus` double NOT NULL,
234 `maturity` int(11) NOT NULL,
235 `disable_scripts` int(11) NOT NULL,
236 `disable_collisions` int(11) NOT NULL,
237 `disable_physics` int(11) NOT NULL,
238 `terrain_texture_1` char(36) NOT NULL,
239 `terrain_texture_2` char(36) NOT NULL,
240 `terrain_texture_3` char(36) NOT NULL,
241 `terrain_texture_4` char(36) NOT NULL,
242 `elevation_1_nw` double NOT NULL,
243 `elevation_2_nw` double NOT NULL,
244 `elevation_1_ne` double NOT NULL,
245 `elevation_2_ne` double NOT NULL,
246 `elevation_1_se` double NOT NULL,
247 `elevation_2_se` double NOT NULL,
248 `elevation_1_sw` double NOT NULL,
249 `elevation_2_sw` double NOT NULL,
250 `water_height` double NOT NULL,
251 `terrain_raise_limit` double NOT NULL,
252 `terrain_lower_limit` double NOT NULL,
253 `use_estate_sun` int(11) NOT NULL,
254 `fixed_sun` int(11) NOT NULL,
255 `sun_position` double NOT NULL,
256 `covenant` char(36) DEFAULT NULL,
257 `Sandbox` tinyint(4) NOT NULL,
258 `sunvectorx` double NOT NULL DEFAULT '0',
259 `sunvectory` double NOT NULL DEFAULT '0',
260 `sunvectorz` double NOT NULL DEFAULT '0',
261 `loaded_creation_id` varchar(64) DEFAULT NULL,
262 `loaded_creation_datetime` int(10) unsigned NOT NULL DEFAULT '0',
263 `map_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
264 `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
265 `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
266 `covenant_datetime` int(10) unsigned NOT NULL DEFAULT '0',
267 PRIMARY KEY (`regionUUID`)
268) ENGINE=MyISAM DEFAULT CHARSET=utf8;
269
270CREATE TABLE IF NOT EXISTS `regionwindlight` (
271 `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
272 `water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000',
273 `water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000',
274 `water_color_b` float(9,6) unsigned NOT NULL DEFAULT '64.000000',
275 `water_fog_density_exponent` float(3,1) unsigned NOT NULL DEFAULT '4.0',
276 `underwater_fog_modifier` float(3,2) unsigned NOT NULL DEFAULT '0.25',
277 `reflection_wavelet_scale_1` float(3,1) unsigned NOT NULL DEFAULT '2.0',
278 `reflection_wavelet_scale_2` float(3,1) unsigned NOT NULL DEFAULT '2.0',
279 `reflection_wavelet_scale_3` float(3,1) unsigned NOT NULL DEFAULT '2.0',
280 `fresnel_scale` float(3,2) unsigned NOT NULL DEFAULT '0.40',
281 `fresnel_offset` float(3,2) unsigned NOT NULL DEFAULT '0.50',
282 `refract_scale_above` float(3,2) unsigned NOT NULL DEFAULT '0.03',
283 `refract_scale_below` float(3,2) unsigned NOT NULL DEFAULT '0.20',
284 `blur_multiplier` float(4,3) unsigned NOT NULL DEFAULT '0.040',
285 `big_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.05',
286 `big_wave_direction_y` float(3,2) NOT NULL DEFAULT '-0.42',
287 `little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11',
288 `little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16',
289 `normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
290 `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.25',
291 `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.25',
292 `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.32',
293 `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.32',
294 `haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19',
295 `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.12',
296 `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.22',
297 `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.38',
298 `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.38',
299 `haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70',
300 `density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18',
301 `distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8',
302 `max_altitude` int(4) unsigned NOT NULL DEFAULT '1605',
303 `sun_moon_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.24',
304 `sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26',
305 `sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30',
306 `sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30',
307 `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.317',
308 `ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35',
309 `ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35',
310 `ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35',
311 `ambient_i` float(3,2) unsigned NOT NULL DEFAULT '0.35',
312 `east_angle` float(3,2) unsigned NOT NULL DEFAULT '0.00',
313 `sun_glow_focus` float(3,2) unsigned NOT NULL DEFAULT '0.10',
314 `sun_glow_size` float(3,2) unsigned NOT NULL DEFAULT '1.75',
315 `scene_gamma` float(4,2) unsigned NOT NULL DEFAULT '1.00',
316 `star_brightness` float(3,2) unsigned NOT NULL DEFAULT '0.00',
317 `cloud_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.41',
318 `cloud_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.41',
319 `cloud_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.41',
320 `cloud_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.41',
321 `cloud_x` float(3,2) unsigned NOT NULL DEFAULT '1.00',
322 `cloud_y` float(3,2) unsigned NOT NULL DEFAULT '0.53',
323 `cloud_density` float(3,2) unsigned NOT NULL DEFAULT '1.00',
324 `cloud_coverage` float(3,2) unsigned NOT NULL DEFAULT '0.27',
325 `cloud_scale` float(3,2) unsigned NOT NULL DEFAULT '0.42',
326 `cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00',
327 `cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53',
328 `cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12',
329 `cloud_scroll_x` float(4,2) NOT NULL DEFAULT '0.20',
330 `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0',
331 `cloud_scroll_y` float(4,2) NOT NULL DEFAULT '0.01',
332 `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0',
333 `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '1',
334 PRIMARY KEY (`region_id`)
335) ENGINE=MyISAM DEFAULT CHARSET=utf8;
336
337CREATE TABLE IF NOT EXISTS `spawn_points` (
338 `RegionID` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
339 `Yaw` float NOT NULL,
340 `Pitch` float NOT NULL,
341 `Distance` float NOT NULL,
342 KEY `RegionID` (`RegionID`)
343) ENGINE=MyISAM DEFAULT CHARSET=utf8;
344
345CREATE TABLE IF NOT EXISTS `regionenvironment` (
346 `region_id` varchar(36) NOT NULL,
347 `llsd_settings` text NOT NULL,
348 PRIMARY KEY (`region_id`)
349) ENGINE=MyISAM DEFAULT CHARSET=utf8;
350
351CREATE TABLE IF NOT EXISTS `regionextra` (
352 `RegionID` char(36) NOT NULL,
353 `Name` varchar(32) NOT NULL,
354 `value` text,
355 PRIMARY KEY (`RegionID`,`Name`)
356) ENGINE=MyISAM DEFAULT CHARSET=utf8;
357
358COMMIT;
359
360:VERSION 52 #---- avination fields
361
362BEGIN;
363
364ALTER TABLE `prims` ADD COLUMN `PassCollisions` tinyint(4) NOT NULL default '0';
365ALTER TABLE `prims` ADD COLUMN `Vehicle` TEXT default NULL;
366ALTER TABLE `regionsettings` ADD COLUMN `block_search` tinyint(4) NOT NULL default '0';
367ALTER TABLE `regionsettings` ADD COLUMN `casino` tinyint(4) NOT NULL default '0';
368ALTER TABLE `land` ADD COLUMN `SeeAVs` tinyint(4) NOT NULL default '1';
369ALTER TABLE `land` ADD COLUMN `AnyAVSounds` tinyint(4) NOT NULL default '1';
370ALTER TABLE `land` ADD COLUMN `GroupAVSounds` tinyint(4) NOT NULL default '1';
371
372COMMIT;
373
374:VERSION 53 #---- STATUS ROTATION axis locks
375
376BEGIN;
377
378ALTER TABLE `prims` ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0';
379
380COMMIT;
381
382:VERSION 54 #----- add baked terrain store
383
384BEGIN;
385
386CREATE TABLE IF NOT EXISTS `bakedterrain` (
387 `RegionUUID` varchar(255) DEFAULT NULL,
388 `Revision` int(11) DEFAULT NULL,
389 `Heightfield` longblob
390) ENGINE=MyISAM DEFAULT CHARSET=utf8;
391
392COMMIT;
393
394:VERSION 55 #----- Increase float precision for windlight needed by scripts
395
396BEGIN;
397
398ALTER TABLE `regionwindlight`
399
400MODIFY `water_fog_density_exponent` float(9,7) unsigned NOT NULL DEFAULT '4.0',
401MODIFY `underwater_fog_modifier` float(9,8) unsigned NOT NULL DEFAULT '0.25',
402MODIFY `reflection_wavelet_scale_1` float(9,7) unsigned NOT NULL DEFAULT '2.0',
403MODIFY `reflection_wavelet_scale_2` float(9,7) unsigned NOT NULL DEFAULT '2.0',
404MODIFY `reflection_wavelet_scale_3` float(9,7) unsigned NOT NULL DEFAULT '2.0',
405MODIFY `fresnel_scale` float(9,8) unsigned NOT NULL DEFAULT '0.40',
406MODIFY `fresnel_offset` float(9,8) unsigned NOT NULL DEFAULT '0.50',
407MODIFY `refract_scale_above` float(9,8) unsigned NOT NULL DEFAULT '0.03',
408MODIFY `refract_scale_below` float(9,8) unsigned NOT NULL DEFAULT '0.20',
409MODIFY `blur_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.040',
410MODIFY `big_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.05',
411MODIFY `big_wave_direction_y` float(9,8) NOT NULL DEFAULT '-0.42',
412MODIFY `little_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.11',
413MODIFY `little_wave_direction_y` float(9,8) NOT NULL DEFAULT '-1.16',
414MODIFY `horizon_r` float(9,8) unsigned NOT NULL DEFAULT '0.25',
415MODIFY `horizon_g` float(9,8) unsigned NOT NULL DEFAULT '0.25',
416MODIFY `horizon_b` float(9,8) unsigned NOT NULL DEFAULT '0.32',
417MODIFY `horizon_i` float(9,8) unsigned NOT NULL DEFAULT '0.32',
418MODIFY `haze_horizon` float(9,8) unsigned NOT NULL DEFAULT '0.19',
419MODIFY `blue_density_r` float(9,8) unsigned NOT NULL DEFAULT '0.12',
420MODIFY `blue_density_g` float(9,8) unsigned NOT NULL DEFAULT '0.22',
421MODIFY `blue_density_b` float(9,8) unsigned NOT NULL DEFAULT '0.38',
422MODIFY `blue_density_i` float(9,8) unsigned NOT NULL DEFAULT '0.38',
423MODIFY `haze_density` float(9,8) unsigned NOT NULL DEFAULT '0.70',
424MODIFY `density_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.18',
425MODIFY `distance_multiplier` float(9,6) unsigned NOT NULL DEFAULT '0.8',
426MODIFY `sun_moon_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.24',
427MODIFY `sun_moon_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.26',
428MODIFY `sun_moon_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.30',
429MODIFY `sun_moon_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.30',
430MODIFY `sun_moon_position` float(9,8) unsigned NOT NULL DEFAULT '0.317',
431MODIFY `ambient_r` float(9,8) unsigned NOT NULL DEFAULT '0.35',
432MODIFY `ambient_g` float(9,8) unsigned NOT NULL DEFAULT '0.35',
433MODIFY `ambient_b` float(9,8) unsigned NOT NULL DEFAULT '0.35',
434MODIFY `ambient_i` float(9,8) unsigned NOT NULL DEFAULT '0.35',
435MODIFY `east_angle` float(9,8) unsigned NOT NULL DEFAULT '0.00',
436MODIFY `sun_glow_focus` float(9,8) unsigned NOT NULL DEFAULT '0.10',
437MODIFY `sun_glow_size` float(9,8) unsigned NOT NULL DEFAULT '1.75',
438MODIFY `scene_gamma` float(9,7) unsigned NOT NULL DEFAULT '1.00',
439MODIFY `star_brightness` float(9,8) unsigned NOT NULL DEFAULT '0.00',
440MODIFY `cloud_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.41',
441MODIFY `cloud_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.41',
442MODIFY `cloud_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.41',
443MODIFY `cloud_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.41',
444MODIFY `cloud_x` float(9,8) unsigned NOT NULL DEFAULT '1.00',
445MODIFY `cloud_y` float(9,8) unsigned NOT NULL DEFAULT '0.53',
446MODIFY `cloud_density` float(9,8) unsigned NOT NULL DEFAULT '1.00',
447MODIFY `cloud_coverage` float(9,8) unsigned NOT NULL DEFAULT '0.27',
448MODIFY `cloud_scale` float(9,8) unsigned NOT NULL DEFAULT '0.42',
449MODIFY `cloud_detail_x` float(9,8) unsigned NOT NULL DEFAULT '1.00',
450MODIFY `cloud_detail_y` float(9,8) unsigned NOT NULL DEFAULT '0.53',
451MODIFY `cloud_detail_density` float(9,8) unsigned NOT NULL DEFAULT '0.12',
452MODIFY `cloud_scroll_x` float(9,7) NOT NULL DEFAULT '0.20',
453MODIFY `cloud_scroll_y` float(9,7) NOT NULL DEFAULT '0.01';
454
455COMMIT;
456
457:VERSION 56 #----- Add RezzerID field in table prims
458
459BEGIN;
460
461ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL;
462
463COMMIT;
464
465:VERSION 57 #----- Add physics inertia data
466
467BEGIN;
468ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL;
469COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/UserAccount.migrations b/OpenSim/Data/MySQL/Resources/UserAccount.migrations
new file mode 100644
index 0000000..dcb375e
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/UserAccount.migrations
@@ -0,0 +1,31 @@
1:VERSION 5 # -------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `UserAccounts` (
6 `PrincipalID` char(36) NOT NULL,
7 `ScopeID` char(36) NOT NULL,
8 `FirstName` varchar(64) NOT NULL,
9 `LastName` varchar(64) NOT NULL,
10 `Email` varchar(64) DEFAULT NULL,
11 `ServiceURLs` text,
12 `Created` int(11) DEFAULT NULL,
13 `UserLevel` int(11) NOT NULL DEFAULT '0',
14 `UserFlags` int(11) NOT NULL DEFAULT '0',
15 `UserTitle` varchar(64) NOT NULL DEFAULT '',
16 UNIQUE KEY `PrincipalID` (`PrincipalID`),
17 KEY `Email` (`Email`),
18 KEY `FirstName` (`FirstName`),
19 KEY `LastName` (`LastName`),
20 KEY `Name` (`FirstName`,`LastName`)
21) ENGINE=MyISAM DEFAULT CHARSET=utf8;
22
23COMMIT;
24
25:VERSION 6 # -------------------------
26
27BEGIN;
28
29ALTER TABLE `UserAccounts` ADD `active` INT NOT NULL DEFAULT '1';
30
31COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/UserProfiles.migrations b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations
new file mode 100644
index 0000000..512b6ed
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations
@@ -0,0 +1,86 @@
1:VERSION 5 # -------------------------------
2
3begin;
4
5CREATE TABLE IF NOT EXISTS `classifieds` (
6 `classifieduuid` char(36) NOT NULL,
7 `creatoruuid` char(36) NOT NULL,
8 `creationdate` int(20) NOT NULL,
9 `expirationdate` int(20) NOT NULL,
10 `category` varchar(20) NOT NULL,
11 `name` varchar(255) NOT NULL,
12 `description` text NOT NULL,
13 `parceluuid` char(36) NOT NULL,
14 `parentestate` int(11) NOT NULL,
15 `snapshotuuid` char(36) NOT NULL,
16 `simname` varchar(255) NOT NULL,
17 `posglobal` varchar(255) NOT NULL,
18 `parcelname` varchar(255) NOT NULL,
19 `classifiedflags` int(8) NOT NULL,
20 `priceforlisting` int(5) NOT NULL,
21 PRIMARY KEY (`classifieduuid`)
22) ENGINE=MyISAM DEFAULT CHARSET=latin1;
23
24
25CREATE TABLE IF NOT EXISTS `usernotes` (
26 `useruuid` varchar(36) NOT NULL,
27 `targetuuid` varchar(36) NOT NULL,
28 `notes` text NOT NULL,
29 UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`)
30) ENGINE=MyISAM DEFAULT CHARSET=latin1;
31
32
33CREATE TABLE IF NOT EXISTS `userpicks` (
34 `pickuuid` varchar(36) NOT NULL,
35 `creatoruuid` varchar(36) NOT NULL,
36 `toppick` enum('true','false') NOT NULL,
37 `parceluuid` varchar(36) NOT NULL,
38 `name` varchar(255) NOT NULL,
39 `description` text NOT NULL,
40 `snapshotuuid` varchar(36) NOT NULL,
41 `user` varchar(255) NOT NULL,
42 `originalname` varchar(255) NOT NULL,
43 `simname` varchar(255) NOT NULL,
44 `posglobal` varchar(255) NOT NULL,
45 `sortorder` int(2) NOT NULL,
46 `enabled` enum('true','false') NOT NULL,
47 `gatekeeper` varchar(255),
48 PRIMARY KEY (`pickuuid`)
49) ENGINE=MyISAM DEFAULT CHARSET=latin1;
50
51
52CREATE TABLE IF NOT EXISTS `userprofile` (
53 `useruuid` varchar(36) NOT NULL,
54 `profilePartner` varchar(36) NOT NULL,
55 `profileAllowPublish` binary(1) NOT NULL,
56 `profileMaturePublish` binary(1) NOT NULL,
57 `profileURL` varchar(255) NOT NULL,
58 `profileWantToMask` int(3) NOT NULL,
59 `profileWantToText` text NOT NULL,
60 `profileSkillsMask` int(3) NOT NULL,
61 `profileSkillsText` text NOT NULL,
62 `profileLanguages` text NOT NULL,
63 `profileImage` varchar(36) NOT NULL,
64 `profileAboutText` text NOT NULL,
65 `profileFirstImage` varchar(36) NOT NULL,
66 `profileFirstText` text NOT NULL,
67 PRIMARY KEY (`useruuid`)
68) ENGINE=MyISAM DEFAULT CHARSET=latin1;
69
70CREATE TABLE IF NOT EXISTS `userdata` (
71 `UserId` char(36) NOT NULL,
72 `TagId` varchar(64) NOT NULL,
73 `DataKey` varchar(255),
74 `DataVal` varchar(255),
75 PRIMARY KEY (`UserId`,`TagId`)
76) ENGINE=MyISAM DEFAULT CHARSET=latin1;
77
78CREATE TABLE IF NOT EXISTS `usersettings` (
79 `useruuid` varchar(36) NOT NULL,
80 `imviaemail` enum('true','false') NOT NULL,
81 `visible` enum('true','false') NOT NULL,
82 `email` varchar(254) NOT NULL,
83 PRIMARY KEY (`useruuid`)
84) ENGINE=MyISAM DEFAULT CHARSET=latin1;
85
86commit;
diff --git a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations
new file mode 100644
index 0000000..7641a97
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations
@@ -0,0 +1,32 @@
1# -----------------
2:VERSION 1
3
4BEGIN;
5
6CREATE TABLE IF NOT EXISTS `XAssetsMeta` (
7 `ID` char(36) NOT NULL,
8 `Hash` binary(32) NOT NULL,
9 `Name` varchar(64) NOT NULL,
10 `Description` varchar(64) NOT NULL,
11 `AssetType` tinyint(4) NOT NULL,
12 `Local` tinyint(1) NOT NULL,
13 `Temporary` tinyint(1) NOT NULL,
14 `CreateTime` int(11) NOT NULL,
15 `AccessTime` int(11) NOT NULL,
16 `AssetFlags` int(11) NOT NULL,
17 `CreatorID` varchar(128) NOT NULL,
18 PRIMARY KEY (`id`)
19) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Version 1';
20
21CREATE TABLE IF NOT EXISTS `XAssetsData` (
22 `Hash` binary(32) NOT NULL,
23 `Data` longblob NOT NULL,
24 PRIMARY KEY (`hash`)
25) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Version 1';
26
27COMMIT;
28
29:VERSION 2
30
31BEGIN;
32COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/XMute.migrations b/OpenSim/Data/MySQL/Resources/XMute.migrations
new file mode 100644
index 0000000..084c67b
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/XMute.migrations
@@ -0,0 +1,16 @@
1:VERSION 1
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `XMute` (
6 `AgentID` char(36) NOT NULL,
7 `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 `MuteName` varchar(64) NOT NULL DEFAULT '',
9 `MuteType` int(11) NOT NULL DEFAULT '1',
10 `MuteFlags` int(11) NOT NULL DEFAULT '0',
11 `Stamp` int(11) NOT NULL,
12 UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`),
13 KEY `AgentID` (`AgentID`)
14) ENGINE=MyISAM DEFAULT CHARSET=utf8;
15
16COMMIT;
diff --git a/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations
new file mode 100644
index 0000000..0b605ab
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations
@@ -0,0 +1,115 @@
1:VERSION 1 # --------------------------
2
3BEGIN;
4
5CREATE TABLE IF NOT EXISTS `os_groups_groups` (
6 `GroupID` char(36) NOT NULL default '',
7 `Location` varchar(255) NOT NULL default '',
8 `Name` varchar(255) NOT NULL default '',
9 `Charter` text NOT NULL,
10 `InsigniaID` char(36) NOT NULL default '',
11 `FounderID` char(36) NOT NULL default '',
12 `MembershipFee` int(11) NOT NULL default '0',
13 `OpenEnrollment` varchar(255) NOT NULL default '',
14 `ShowInList` int(4) NOT NULL default '0',
15 `AllowPublish` int(4) NOT NULL default '0',
16 `MaturePublish` int(4) NOT NULL default '0',
17 `OwnerRoleID` char(36) NOT NULL default '',
18 PRIMARY KEY (`GroupID`),
19 UNIQUE KEY `Name` (`Name`),
20 FULLTEXT KEY `Name_2` (`Name`)
21) ENGINE=MyISAM DEFAULT CHARSET=utf8;
22
23
24CREATE TABLE IF NOT EXISTS `os_groups_membership` (
25 `GroupID`char(36) NOT NULL default '',
26 `PrincipalID` VARCHAR(255) NOT NULL default '',
27 `SelectedRoleID` char(36) NOT NULL default '',
28 `Contribution` int(11) NOT NULL default '0',
29 `ListInProfile` int(4) NOT NULL default '1',
30 `AcceptNotices` int(4) NOT NULL default '1',
31 `AccessToken` char(36) NOT NULL default '',
32 PRIMARY KEY (`GroupID`,`PrincipalID`),
33 KEY `PrincipalID` (`PrincipalID`)
34) ENGINE=MyISAM DEFAULT CHARSET=utf8;
35
36
37CREATE TABLE IF NOT EXISTS `os_groups_roles` (
38 `GroupID` char(36) NOT NULL default '',
39 `RoleID` char(36) NOT NULL default '',
40 `Name` varchar(255) NOT NULL default '',
41 `Description` varchar(255) NOT NULL default '',
42 `Title` varchar(255) NOT NULL default '',
43 `Powers` bigint(20) unsigned NOT NULL default '0',
44 PRIMARY KEY (`GroupID`,`RoleID`),
45 KEY `GroupID` (`GroupID`)
46) ENGINE=MyISAM DEFAULT CHARSET=utf8;
47
48
49CREATE TABLE IF NOT EXISTS `os_groups_rolemembership` (
50 `GroupID` char(36) NOT NULL default '',
51 `RoleID` char(36) NOT NULL default '',
52 `PrincipalID` VARCHAR(255) NOT NULL default '',
53 PRIMARY KEY (`GroupID`,`RoleID`,`PrincipalID`),
54 KEY `PrincipalID` (`PrincipalID`)
55) ENGINE=MyISAM DEFAULT CHARSET=utf8;
56
57
58CREATE TABLE IF NOT EXISTS `os_groups_invites` (
59 `InviteID` char(36) NOT NULL default '',
60 `GroupID` char(36) NOT NULL default '',
61 `RoleID` char(36) NOT NULL default '',
62 `PrincipalID` VARCHAR(255) NOT NULL default '',
63 `TMStamp` timestamp NOT NULL,
64 PRIMARY KEY (`InviteID`),
65 UNIQUE KEY `PrincipalGroup` (`GroupID`,`PrincipalID`)
66) ENGINE=MyISAM DEFAULT CHARSET=utf8;
67
68
69CREATE TABLE IF NOT EXISTS `os_groups_notices` (
70 `GroupID` char(36) NOT NULL default '',
71 `NoticeID` char(36) NOT NULL default '',
72 `TMStamp` int(10) unsigned NOT NULL default '0',
73 `FromName` varchar(255) NOT NULL default '',
74 `Subject` varchar(255) NOT NULL default '',
75 `Message` text NOT NULL,
76 `HasAttachment` int(4) NOT NULL default '0',
77 `AttachmentType` int(4) NOT NULL default '0',
78 `AttachmentName` varchar(128) NOT NULL default '',
79 `AttachmentItemID` char(36) NOT NULL default '',
80 `AttachmentOwnerID` varchar(255) NOT NULL default '',
81 PRIMARY KEY (`NoticeID`),
82 KEY `GroupID` (`GroupID`),
83 KEY `TMStamp` (`TMStamp`)
84) ENGINE=MyISAM DEFAULT CHARSET=utf8;
85
86CREATE TABLE IF NOT EXISTS `os_groups_principals` (
87 `PrincipalID` VARCHAR(255) NOT NULL default '',
88 `ActiveGroupID` char(36) NOT NULL default '',
89 PRIMARY KEY (`PrincipalID`)
90) ENGINE=MyISAM DEFAULT CHARSET=utf8;
91
92COMMIT;
93
94:VERSION 2 # --------------------------
95
96BEGIN;
97
98INSERT INTO `os_groups_groups` SELECT * from `diva_groups_groups`;
99DROP TABLE `diva_groups_groups`;
100INSERT INTO `os_groups_membership` SELECT * from `diva_groups_membership`;
101DROP TABLE `diva_groups_membership`;
102INSERT INTO `os_groups_roles` SELECT * from `diva_groups_roles`;
103DROP TABLE `diva_groups_roles`;
104INSERT INTO `os_groups_rolemembership` SELECT * from `diva_groups_rolemembership`;
105DROP TABLE `diva_groups_rolemembership`;
106INSERT INTO `os_groups_invites` SELECT * from `diva_groups_invites`;
107DROP TABLE `diva_groups_invites`;
108INSERT INTO `os_groups_notices` SELECT * from `diva_groups_notices`;
109DROP TABLE `diva_groups_notices`;
110INSERT INTO `os_groups_principals` SELECT * from `diva_groups_principals`;
111DROP TABLE `diva_groups_principals`;
112
113DELETE FROM `migrations` WHERE name='diva_im_Store';
114
115COMMIT;