diff options
author | UbitUmarov | 2015-09-01 11:43:07 +0100 |
---|---|---|
committer | UbitUmarov | 2015-09-01 11:43:07 +0100 |
commit | fb78b182520fc9bb0f971afd0322029c70278ea6 (patch) | |
tree | b4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Data/MySQL | |
parent | lixo (diff) | |
parent | Mantis #7713: fixed bug introduced by 1st MOSES patch. (diff) | |
download | opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2 opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz |
Merge remote-tracking branch 'os/master'
Diffstat (limited to '')
43 files changed, 10594 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs new file mode 100644 index 0000000..ed0ab98 --- /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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using MySql.Data.MySqlClient; | ||
35 | |||
36 | namespace 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..5d8da17 --- /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 | |||
28 | using System; | ||
29 | using System.Data; | ||
30 | using System.Reflection; | ||
31 | using System.Collections.Generic; | ||
32 | using log4net; | ||
33 | using MySql.Data.MySqlClient; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Data; | ||
37 | |||
38 | namespace 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 | } | ||
79 | } | ||
80 | |||
81 | public override void Initialise() | ||
82 | { | ||
83 | throw new NotImplementedException(); | ||
84 | } | ||
85 | |||
86 | public override void Dispose() { } | ||
87 | |||
88 | /// <summary> | ||
89 | /// The name of this DB provider | ||
90 | /// </summary> | ||
91 | override public string Name | ||
92 | { | ||
93 | get { return "MySQL Asset storage engine"; } | ||
94 | } | ||
95 | |||
96 | #endregion | ||
97 | |||
98 | #region IAssetDataPlugin Members | ||
99 | |||
100 | /// <summary> | ||
101 | /// Fetch Asset <paramref name="assetID"/> from database | ||
102 | /// </summary> | ||
103 | /// <param name="assetID">Asset UUID to fetch</param> | ||
104 | /// <returns>Return the asset</returns> | ||
105 | /// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks> | ||
106 | override public AssetBase GetAsset(UUID assetID) | ||
107 | { | ||
108 | AssetBase asset = null; | ||
109 | |||
110 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
111 | { | ||
112 | dbcon.Open(); | ||
113 | |||
114 | using (MySqlCommand cmd = new MySqlCommand( | ||
115 | "SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id", | ||
116 | dbcon)) | ||
117 | { | ||
118 | cmd.Parameters.AddWithValue("?id", assetID.ToString()); | ||
119 | |||
120 | try | ||
121 | { | ||
122 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
123 | { | ||
124 | if (dbReader.Read()) | ||
125 | { | ||
126 | asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString()); | ||
127 | asset.Data = (byte[])dbReader["data"]; | ||
128 | asset.Description = (string)dbReader["description"]; | ||
129 | |||
130 | string local = dbReader["local"].ToString(); | ||
131 | if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) | ||
132 | asset.Local = true; | ||
133 | else | ||
134 | asset.Local = false; | ||
135 | |||
136 | asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); | ||
137 | asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | catch (Exception e) | ||
142 | { | ||
143 | m_log.Error( | ||
144 | string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e); | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return asset; | ||
150 | } | ||
151 | |||
152 | /// <summary> | ||
153 | /// Create an asset in database, or update it if existing. | ||
154 | /// </summary> | ||
155 | /// <param name="asset">Asset UUID to create</param> | ||
156 | /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> | ||
157 | override public void StoreAsset(AssetBase asset) | ||
158 | { | ||
159 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
160 | { | ||
161 | dbcon.Open(); | ||
162 | |||
163 | using (MySqlCommand cmd = | ||
164 | new MySqlCommand( | ||
165 | "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + | ||
166 | "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)", | ||
167 | dbcon)) | ||
168 | { | ||
169 | string assetName = asset.Name; | ||
170 | if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) | ||
171 | { | ||
172 | assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); | ||
173 | m_log.WarnFormat( | ||
174 | "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
175 | asset.Name, asset.ID, asset.Name.Length, assetName.Length); | ||
176 | } | ||
177 | |||
178 | string assetDescription = asset.Description; | ||
179 | if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) | ||
180 | { | ||
181 | assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); | ||
182 | m_log.WarnFormat( | ||
183 | "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
184 | asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); | ||
185 | } | ||
186 | |||
187 | try | ||
188 | { | ||
189 | using (cmd) | ||
190 | { | ||
191 | // create unix epoch time | ||
192 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
193 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
194 | cmd.Parameters.AddWithValue("?name", assetName); | ||
195 | cmd.Parameters.AddWithValue("?description", assetDescription); | ||
196 | cmd.Parameters.AddWithValue("?assetType", asset.Type); | ||
197 | cmd.Parameters.AddWithValue("?local", asset.Local); | ||
198 | cmd.Parameters.AddWithValue("?temporary", asset.Temporary); | ||
199 | cmd.Parameters.AddWithValue("?create_time", now); | ||
200 | cmd.Parameters.AddWithValue("?access_time", now); | ||
201 | cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); | ||
202 | cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); | ||
203 | cmd.Parameters.AddWithValue("?data", asset.Data); | ||
204 | cmd.ExecuteNonQuery(); | ||
205 | } | ||
206 | } | ||
207 | catch (Exception e) | ||
208 | { | ||
209 | m_log.Error( | ||
210 | string.Format( | ||
211 | "[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ", | ||
212 | asset.FullID, asset.Name) | ||
213 | , e); | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | private void UpdateAccessTime(AssetBase asset) | ||
220 | { | ||
221 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
222 | { | ||
223 | dbcon.Open(); | ||
224 | |||
225 | using (MySqlCommand cmd | ||
226 | = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon)) | ||
227 | { | ||
228 | try | ||
229 | { | ||
230 | using (cmd) | ||
231 | { | ||
232 | // create unix epoch time | ||
233 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
234 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
235 | cmd.Parameters.AddWithValue("?access_time", now); | ||
236 | cmd.ExecuteNonQuery(); | ||
237 | } | ||
238 | } | ||
239 | catch (Exception e) | ||
240 | { | ||
241 | m_log.Error( | ||
242 | string.Format( | ||
243 | "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ", | ||
244 | asset.FullID, asset.Name), | ||
245 | e); | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /// <summary> | ||
252 | /// Check if the assets exist in the database. | ||
253 | /// </summary> | ||
254 | /// <param name="uuidss">The assets' IDs</param> | ||
255 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
256 | public override bool[] AssetsExist(UUID[] uuids) | ||
257 | { | ||
258 | if (uuids.Length == 0) | ||
259 | return new bool[0]; | ||
260 | |||
261 | HashSet<UUID> exist = new HashSet<UUID>(); | ||
262 | |||
263 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
264 | string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids); | ||
265 | |||
266 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
267 | { | ||
268 | dbcon.Open(); | ||
269 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
270 | { | ||
271 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
272 | { | ||
273 | while (dbReader.Read()) | ||
274 | { | ||
275 | UUID id = DBGuid.FromDB(dbReader["id"]); | ||
276 | exist.Add(id); | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | |||
282 | bool[] results = new bool[uuids.Length]; | ||
283 | for (int i = 0; i < uuids.Length; i++) | ||
284 | results[i] = exist.Contains(uuids[i]); | ||
285 | |||
286 | return results; | ||
287 | } | ||
288 | |||
289 | /// <summary> | ||
290 | /// Returns a list of AssetMetadata objects. The list is a subset of | ||
291 | /// the entire data set offset by <paramref name="start" /> containing | ||
292 | /// <paramref name="count" /> elements. | ||
293 | /// </summary> | ||
294 | /// <param name="start">The number of results to discard from the total data set.</param> | ||
295 | /// <param name="count">The number of rows the returned list should contain.</param> | ||
296 | /// <returns>A list of AssetMetadata objects.</returns> | ||
297 | public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count) | ||
298 | { | ||
299 | List<AssetMetadata> retList = new List<AssetMetadata>(count); | ||
300 | |||
301 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
302 | { | ||
303 | dbcon.Open(); | ||
304 | |||
305 | using (MySqlCommand cmd | ||
306 | = new MySqlCommand( | ||
307 | "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", | ||
308 | dbcon)) | ||
309 | { | ||
310 | cmd.Parameters.AddWithValue("?start", start); | ||
311 | cmd.Parameters.AddWithValue("?count", count); | ||
312 | |||
313 | try | ||
314 | { | ||
315 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
316 | { | ||
317 | while (dbReader.Read()) | ||
318 | { | ||
319 | AssetMetadata metadata = new AssetMetadata(); | ||
320 | metadata.Name = (string)dbReader["name"]; | ||
321 | metadata.Description = (string)dbReader["description"]; | ||
322 | metadata.Type = (sbyte)dbReader["assetType"]; | ||
323 | metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. | ||
324 | metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | ||
325 | metadata.FullID = DBGuid.FromDB(dbReader["id"]); | ||
326 | metadata.CreatorID = dbReader["CreatorID"].ToString(); | ||
327 | |||
328 | // Current SHA1s are not stored/computed. | ||
329 | metadata.SHA1 = new byte[] { }; | ||
330 | |||
331 | retList.Add(metadata); | ||
332 | } | ||
333 | } | ||
334 | } | ||
335 | catch (Exception e) | ||
336 | { | ||
337 | m_log.Error( | ||
338 | string.Format( | ||
339 | "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ", | ||
340 | start, count), | ||
341 | e); | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | |||
346 | return retList; | ||
347 | } | ||
348 | |||
349 | public override bool Delete(string id) | ||
350 | { | ||
351 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
352 | { | ||
353 | dbcon.Open(); | ||
354 | |||
355 | using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon)) | ||
356 | { | ||
357 | cmd.Parameters.AddWithValue("?id", id); | ||
358 | cmd.ExecuteNonQuery(); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | return true; | ||
363 | } | ||
364 | |||
365 | #endregion | ||
366 | } | ||
367 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs new file mode 100644 index 0000000..7627497 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using System.Data; | ||
33 | using OpenMetaverse; | ||
34 | using OpenSim.Framework; | ||
35 | using MySql.Data.MySqlClient; | ||
36 | |||
37 | namespace 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 | } | ||
63 | } | ||
64 | |||
65 | public AuthenticationData Get(UUID principalID) | ||
66 | { | ||
67 | AuthenticationData ret = new AuthenticationData(); | ||
68 | ret.Data = new Dictionary<string, object>(); | ||
69 | |||
70 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
71 | { | ||
72 | dbcon.Open(); | ||
73 | |||
74 | using (MySqlCommand cmd | ||
75 | = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon)) | ||
76 | { | ||
77 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
78 | |||
79 | IDataReader result = cmd.ExecuteReader(); | ||
80 | |||
81 | if (result.Read()) | ||
82 | { | ||
83 | ret.PrincipalID = principalID; | ||
84 | |||
85 | CheckColumnNames(result); | ||
86 | |||
87 | foreach (string s in m_ColumnNames) | ||
88 | { | ||
89 | if (s == "UUID") | ||
90 | continue; | ||
91 | |||
92 | ret.Data[s] = result[s].ToString(); | ||
93 | } | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | return null; | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | private void CheckColumnNames(IDataReader result) | ||
106 | { | ||
107 | if (m_ColumnNames != null) | ||
108 | return; | ||
109 | |||
110 | List<string> columnNames = new List<string>(); | ||
111 | |||
112 | DataTable schemaTable = result.GetSchemaTable(); | ||
113 | foreach (DataRow row in schemaTable.Rows) | ||
114 | columnNames.Add(row["ColumnName"].ToString()); | ||
115 | |||
116 | m_ColumnNames = columnNames; | ||
117 | } | ||
118 | |||
119 | public bool Store(AuthenticationData data) | ||
120 | { | ||
121 | if (data.Data.ContainsKey("UUID")) | ||
122 | data.Data.Remove("UUID"); | ||
123 | |||
124 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
125 | |||
126 | using (MySqlCommand cmd = new MySqlCommand()) | ||
127 | { | ||
128 | string update = "update `"+m_Realm+"` set "; | ||
129 | bool first = true; | ||
130 | foreach (string field in fields) | ||
131 | { | ||
132 | if (!first) | ||
133 | update += ", "; | ||
134 | update += "`" + field + "` = ?"+field; | ||
135 | |||
136 | first = false; | ||
137 | |||
138 | cmd.Parameters.AddWithValue("?"+field, data.Data[field]); | ||
139 | } | ||
140 | |||
141 | update += " where UUID = ?principalID"; | ||
142 | |||
143 | cmd.CommandText = update; | ||
144 | cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); | ||
145 | |||
146 | if (ExecuteNonQuery(cmd) < 1) | ||
147 | { | ||
148 | string insert = "insert into `" + m_Realm + "` (`UUID`, `" + | ||
149 | String.Join("`, `", fields) + | ||
150 | "`) values (?principalID, ?" + String.Join(", ?", fields) + ")"; | ||
151 | |||
152 | cmd.CommandText = insert; | ||
153 | |||
154 | if (ExecuteNonQuery(cmd) < 1) | ||
155 | return false; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | return true; | ||
160 | } | ||
161 | |||
162 | public bool SetDataItem(UUID principalID, string item, string value) | ||
163 | { | ||
164 | using (MySqlCommand cmd | ||
165 | = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID")) | ||
166 | { | ||
167 | cmd.Parameters.AddWithValue("?"+item, value); | ||
168 | cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); | ||
169 | |||
170 | if (ExecuteNonQuery(cmd) > 0) | ||
171 | return true; | ||
172 | } | ||
173 | |||
174 | return false; | ||
175 | } | ||
176 | |||
177 | public bool SetToken(UUID principalID, string token, int lifetime) | ||
178 | { | ||
179 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
180 | DoExpire(); | ||
181 | |||
182 | using (MySqlCommand cmd | ||
183 | = new MySqlCommand( | ||
184 | "insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))")) | ||
185 | { | ||
186 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
187 | cmd.Parameters.AddWithValue("?token", token); | ||
188 | cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); | ||
189 | |||
190 | if (ExecuteNonQuery(cmd) > 0) | ||
191 | return true; | ||
192 | } | ||
193 | |||
194 | return false; | ||
195 | } | ||
196 | |||
197 | public bool CheckToken(UUID principalID, string token, int lifetime) | ||
198 | { | ||
199 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
200 | DoExpire(); | ||
201 | |||
202 | using (MySqlCommand cmd | ||
203 | = new MySqlCommand( | ||
204 | "update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()")) | ||
205 | { | ||
206 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
207 | cmd.Parameters.AddWithValue("?token", token); | ||
208 | cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); | ||
209 | |||
210 | if (ExecuteNonQuery(cmd) > 0) | ||
211 | return true; | ||
212 | } | ||
213 | |||
214 | return false; | ||
215 | } | ||
216 | |||
217 | private void DoExpire() | ||
218 | { | ||
219 | using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()")) | ||
220 | { | ||
221 | ExecuteNonQuery(cmd); | ||
222 | } | ||
223 | |||
224 | m_LastExpire = System.Environment.TickCount; | ||
225 | } | ||
226 | } | ||
227 | } \ 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..6a2f5d8 --- /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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | |||
38 | namespace 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..fe1487b --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs | |||
@@ -0,0 +1,594 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using MySql.Data.MySqlClient; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Region.Framework.Interfaces; | ||
37 | using OpenSim.Data; | ||
38 | |||
39 | namespace 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 | |||
86 | Type t = typeof(EstateSettings); | ||
87 | m_Fields = t.GetFields(BindingFlags.NonPublic | | ||
88 | BindingFlags.Instance | | ||
89 | BindingFlags.DeclaredOnly); | ||
90 | |||
91 | foreach (FieldInfo f in m_Fields) | ||
92 | { | ||
93 | if (f.Name.Substring(0, 2) == "m_") | ||
94 | m_FieldMap[f.Name.Substring(2)] = f; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | private string[] FieldList | ||
100 | { | ||
101 | get { return new List<string>(m_FieldMap.Keys).ToArray(); } | ||
102 | } | ||
103 | |||
104 | public EstateSettings LoadEstateSettings(UUID regionID, bool create) | ||
105 | { | ||
106 | string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + | ||
107 | " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID"; | ||
108 | |||
109 | using (MySqlCommand cmd = new MySqlCommand()) | ||
110 | { | ||
111 | cmd.CommandText = sql; | ||
112 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
113 | |||
114 | EstateSettings e = DoLoad(cmd, regionID, create); | ||
115 | if (!create && e.EstateID == 0) // Not found | ||
116 | return null; | ||
117 | |||
118 | return e; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | public EstateSettings CreateNewEstate() | ||
123 | { | ||
124 | EstateSettings es = new EstateSettings(); | ||
125 | es.OnSave += StoreEstateSettings; | ||
126 | |||
127 | DoCreate(es); | ||
128 | |||
129 | LoadBanList(es); | ||
130 | |||
131 | es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); | ||
132 | es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); | ||
133 | es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); | ||
134 | |||
135 | return es; | ||
136 | } | ||
137 | |||
138 | private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create) | ||
139 | { | ||
140 | EstateSettings es = new EstateSettings(); | ||
141 | es.OnSave += StoreEstateSettings; | ||
142 | |||
143 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
144 | { | ||
145 | dbcon.Open(); | ||
146 | |||
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 | |||
175 | if (!found && create) | ||
176 | { | ||
177 | DoCreate(es); | ||
178 | LinkRegion(regionID, (int)es.EstateID); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | LoadBanList(es); | ||
183 | es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); | ||
184 | es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); | ||
185 | es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); | ||
186 | return es; | ||
187 | } | ||
188 | |||
189 | private void DoCreate(EstateSettings es) | ||
190 | { | ||
191 | // Migration case | ||
192 | List<string> names = new List<string>(FieldList); | ||
193 | |||
194 | names.Remove("EstateID"); | ||
195 | |||
196 | string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; | ||
197 | |||
198 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
199 | { | ||
200 | dbcon.Open(); | ||
201 | using (MySqlCommand cmd2 = dbcon.CreateCommand()) | ||
202 | { | ||
203 | cmd2.CommandText = sql; | ||
204 | cmd2.Parameters.Clear(); | ||
205 | |||
206 | foreach (string name in FieldList) | ||
207 | { | ||
208 | if (m_FieldMap[name].GetValue(es) is bool) | ||
209 | { | ||
210 | if ((bool)m_FieldMap[name].GetValue(es)) | ||
211 | cmd2.Parameters.AddWithValue("?" + name, "1"); | ||
212 | else | ||
213 | cmd2.Parameters.AddWithValue("?" + name, "0"); | ||
214 | } | ||
215 | else | ||
216 | { | ||
217 | cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | cmd2.ExecuteNonQuery(); | ||
222 | |||
223 | cmd2.CommandText = "select LAST_INSERT_ID() as id"; | ||
224 | cmd2.Parameters.Clear(); | ||
225 | |||
226 | using (IDataReader r = cmd2.ExecuteReader()) | ||
227 | { | ||
228 | r.Read(); | ||
229 | es.EstateID = Convert.ToUInt32(r["id"]); | ||
230 | } | ||
231 | |||
232 | es.Save(); | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | public void StoreEstateSettings(EstateSettings es) | ||
238 | { | ||
239 | string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")"; | ||
240 | |||
241 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
242 | { | ||
243 | dbcon.Open(); | ||
244 | |||
245 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
246 | { | ||
247 | cmd.CommandText = sql; | ||
248 | |||
249 | foreach (string name in FieldList) | ||
250 | { | ||
251 | if (m_FieldMap[name].GetValue(es) is bool) | ||
252 | { | ||
253 | if ((bool)m_FieldMap[name].GetValue(es)) | ||
254 | cmd.Parameters.AddWithValue("?" + name, "1"); | ||
255 | else | ||
256 | cmd.Parameters.AddWithValue("?" + name, "0"); | ||
257 | } | ||
258 | else | ||
259 | { | ||
260 | cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | cmd.ExecuteNonQuery(); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | SaveBanList(es); | ||
269 | SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); | ||
270 | SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess); | ||
271 | SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups); | ||
272 | } | ||
273 | |||
274 | private void LoadBanList(EstateSettings es) | ||
275 | { | ||
276 | es.ClearBans(); | ||
277 | |||
278 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
279 | { | ||
280 | dbcon.Open(); | ||
281 | |||
282 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
283 | { | ||
284 | cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID"; | ||
285 | cmd.Parameters.AddWithValue("?EstateID", es.EstateID); | ||
286 | |||
287 | using (IDataReader r = cmd.ExecuteReader()) | ||
288 | { | ||
289 | while (r.Read()) | ||
290 | { | ||
291 | EstateBan eb = new EstateBan(); | ||
292 | |||
293 | UUID uuid = new UUID(); | ||
294 | UUID.TryParse(r["bannedUUID"].ToString(), out uuid); | ||
295 | |||
296 | eb.BannedUserID = uuid; | ||
297 | eb.BannedHostAddress = "0.0.0.0"; | ||
298 | eb.BannedHostIPMask = "0.0.0.0"; | ||
299 | es.AddBan(eb); | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | |||
306 | private void SaveBanList(EstateSettings es) | ||
307 | { | ||
308 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
309 | { | ||
310 | dbcon.Open(); | ||
311 | |||
312 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
313 | { | ||
314 | cmd.CommandText = "delete from estateban where EstateID = ?EstateID"; | ||
315 | cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); | ||
316 | |||
317 | cmd.ExecuteNonQuery(); | ||
318 | |||
319 | cmd.Parameters.Clear(); | ||
320 | |||
321 | cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )"; | ||
322 | |||
323 | foreach (EstateBan b in es.EstateBans) | ||
324 | { | ||
325 | cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); | ||
326 | cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString()); | ||
327 | |||
328 | cmd.ExecuteNonQuery(); | ||
329 | cmd.Parameters.Clear(); | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | void SaveUUIDList(uint EstateID, string table, UUID[] data) | ||
336 | { | ||
337 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
338 | { | ||
339 | dbcon.Open(); | ||
340 | |||
341 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
342 | { | ||
343 | cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID"; | ||
344 | cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); | ||
345 | |||
346 | cmd.ExecuteNonQuery(); | ||
347 | |||
348 | cmd.Parameters.Clear(); | ||
349 | |||
350 | cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )"; | ||
351 | |||
352 | foreach (UUID uuid in data) | ||
353 | { | ||
354 | cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); | ||
355 | cmd.Parameters.AddWithValue("?uuid", uuid.ToString()); | ||
356 | |||
357 | cmd.ExecuteNonQuery(); | ||
358 | cmd.Parameters.Clear(); | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | } | ||
363 | |||
364 | UUID[] LoadUUIDList(uint EstateID, string table) | ||
365 | { | ||
366 | List<UUID> uuids = new List<UUID>(); | ||
367 | |||
368 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
369 | { | ||
370 | dbcon.Open(); | ||
371 | |||
372 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
373 | { | ||
374 | cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID"; | ||
375 | cmd.Parameters.AddWithValue("?EstateID", EstateID); | ||
376 | |||
377 | using (IDataReader r = cmd.ExecuteReader()) | ||
378 | { | ||
379 | while (r.Read()) | ||
380 | { | ||
381 | // EstateBan eb = new EstateBan(); | ||
382 | uuids.Add(DBGuid.FromDB(r["uuid"])); | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | |||
388 | return uuids.ToArray(); | ||
389 | } | ||
390 | |||
391 | public EstateSettings LoadEstateSettings(int estateID) | ||
392 | { | ||
393 | using (MySqlCommand cmd = new MySqlCommand()) | ||
394 | { | ||
395 | string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = ?EstateID"; | ||
396 | |||
397 | cmd.CommandText = sql; | ||
398 | cmd.Parameters.AddWithValue("?EstateID", estateID); | ||
399 | |||
400 | EstateSettings e = DoLoad(cmd, UUID.Zero, false); | ||
401 | if (e.EstateID != estateID) | ||
402 | return null; | ||
403 | return e; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | public List<EstateSettings> LoadEstateSettingsAll() | ||
408 | { | ||
409 | List<EstateSettings> allEstateSettings = new List<EstateSettings>(); | ||
410 | |||
411 | List<int> allEstateIds = GetEstatesAll(); | ||
412 | |||
413 | foreach (int estateId in allEstateIds) | ||
414 | allEstateSettings.Add(LoadEstateSettings(estateId)); | ||
415 | |||
416 | return allEstateSettings; | ||
417 | } | ||
418 | |||
419 | public List<int> GetEstatesAll() | ||
420 | { | ||
421 | List<int> result = new List<int>(); | ||
422 | |||
423 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
424 | { | ||
425 | dbcon.Open(); | ||
426 | |||
427 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
428 | { | ||
429 | cmd.CommandText = "select estateID from estate_settings"; | ||
430 | |||
431 | using (IDataReader reader = cmd.ExecuteReader()) | ||
432 | { | ||
433 | while (reader.Read()) | ||
434 | { | ||
435 | result.Add(Convert.ToInt32(reader["EstateID"])); | ||
436 | } | ||
437 | reader.Close(); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | dbcon.Close(); | ||
442 | } | ||
443 | |||
444 | return result; | ||
445 | } | ||
446 | |||
447 | public List<int> GetEstates(string search) | ||
448 | { | ||
449 | List<int> result = new List<int>(); | ||
450 | |||
451 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
452 | { | ||
453 | dbcon.Open(); | ||
454 | |||
455 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
456 | { | ||
457 | cmd.CommandText = "select estateID from estate_settings where EstateName = ?EstateName"; | ||
458 | cmd.Parameters.AddWithValue("?EstateName", search); | ||
459 | |||
460 | using (IDataReader reader = cmd.ExecuteReader()) | ||
461 | { | ||
462 | while (reader.Read()) | ||
463 | { | ||
464 | result.Add(Convert.ToInt32(reader["EstateID"])); | ||
465 | } | ||
466 | reader.Close(); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | dbcon.Close(); | ||
471 | } | ||
472 | |||
473 | return result; | ||
474 | } | ||
475 | |||
476 | public List<int> GetEstatesByOwner(UUID ownerID) | ||
477 | { | ||
478 | List<int> result = new List<int>(); | ||
479 | |||
480 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
481 | { | ||
482 | dbcon.Open(); | ||
483 | |||
484 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
485 | { | ||
486 | cmd.CommandText = "select estateID from estate_settings where EstateOwner = ?EstateOwner"; | ||
487 | cmd.Parameters.AddWithValue("?EstateOwner", ownerID); | ||
488 | |||
489 | using (IDataReader reader = cmd.ExecuteReader()) | ||
490 | { | ||
491 | while (reader.Read()) | ||
492 | { | ||
493 | result.Add(Convert.ToInt32(reader["EstateID"])); | ||
494 | } | ||
495 | reader.Close(); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | dbcon.Close(); | ||
500 | } | ||
501 | |||
502 | return result; | ||
503 | } | ||
504 | |||
505 | public bool LinkRegion(UUID regionID, int estateID) | ||
506 | { | ||
507 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
508 | { | ||
509 | dbcon.Open(); | ||
510 | MySqlTransaction transaction = dbcon.BeginTransaction(); | ||
511 | |||
512 | try | ||
513 | { | ||
514 | // Delete any existing association of this region with an estate. | ||
515 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
516 | { | ||
517 | cmd.Transaction = transaction; | ||
518 | cmd.CommandText = "delete from estate_map where RegionID = ?RegionID"; | ||
519 | cmd.Parameters.AddWithValue("?RegionID", regionID); | ||
520 | |||
521 | cmd.ExecuteNonQuery(); | ||
522 | } | ||
523 | |||
524 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
525 | { | ||
526 | cmd.Transaction = transaction; | ||
527 | cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; | ||
528 | cmd.Parameters.AddWithValue("?RegionID", regionID); | ||
529 | cmd.Parameters.AddWithValue("?EstateID", estateID); | ||
530 | |||
531 | int ret = cmd.ExecuteNonQuery(); | ||
532 | |||
533 | if (ret != 0) | ||
534 | transaction.Commit(); | ||
535 | else | ||
536 | transaction.Rollback(); | ||
537 | |||
538 | dbcon.Close(); | ||
539 | |||
540 | return (ret != 0); | ||
541 | } | ||
542 | } | ||
543 | catch (MySqlException ex) | ||
544 | { | ||
545 | m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message); | ||
546 | transaction.Rollback(); | ||
547 | } | ||
548 | |||
549 | dbcon.Close(); | ||
550 | } | ||
551 | |||
552 | return false; | ||
553 | } | ||
554 | |||
555 | public List<UUID> GetRegions(int estateID) | ||
556 | { | ||
557 | List<UUID> result = new List<UUID>(); | ||
558 | |||
559 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
560 | { | ||
561 | dbcon.Open(); | ||
562 | |||
563 | try | ||
564 | { | ||
565 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
566 | { | ||
567 | cmd.CommandText = "select RegionID from estate_map where EstateID = ?EstateID"; | ||
568 | cmd.Parameters.AddWithValue("?EstateID", estateID.ToString()); | ||
569 | |||
570 | using (IDataReader reader = cmd.ExecuteReader()) | ||
571 | { | ||
572 | while(reader.Read()) | ||
573 | result.Add(DBGuid.FromDB(reader["RegionID"])); | ||
574 | reader.Close(); | ||
575 | } | ||
576 | } | ||
577 | } | ||
578 | catch (Exception e) | ||
579 | { | ||
580 | m_log.Error("[REGION DB]: Error reading estate map. " + e.ToString()); | ||
581 | return result; | ||
582 | } | ||
583 | dbcon.Close(); | ||
584 | } | ||
585 | |||
586 | return result; | ||
587 | } | ||
588 | |||
589 | public bool DeleteEstate(int estateID) | ||
590 | { | ||
591 | return false; | ||
592 | } | ||
593 | } | ||
594 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs new file mode 100644 index 0000000..19e23b5 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Framework.Console; | ||
34 | using log4net; | ||
35 | using MySql.Data.MySqlClient; | ||
36 | using OpenMetaverse; | ||
37 | |||
38 | namespace 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 MySqlConnection m_Connection = null; | ||
45 | protected string m_ConnectionString; | ||
46 | protected string m_Table; | ||
47 | protected Object m_connLock = new Object(); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Number of days that must pass before we update the access time on an asset when it has been fetched | ||
51 | /// Config option to change this is "DaysBetweenAccessTimeUpdates" | ||
52 | /// </summary> | ||
53 | private int DaysBetweenAccessTimeUpdates = 0; | ||
54 | |||
55 | protected virtual Assembly Assembly | ||
56 | { | ||
57 | get { return GetType().Assembly; } | ||
58 | } | ||
59 | |||
60 | public MySQLFSAssetData() | ||
61 | { | ||
62 | } | ||
63 | |||
64 | #region IPlugin Members | ||
65 | |||
66 | public string Version { get { return "1.0.0.0"; } } | ||
67 | |||
68 | // Loads and initialises the MySQL storage plugin and checks for migrations | ||
69 | public void Initialise(string connect, string realm, int UpdateAccessTime) | ||
70 | { | ||
71 | m_ConnectionString = connect; | ||
72 | m_Table = realm; | ||
73 | |||
74 | DaysBetweenAccessTimeUpdates = UpdateAccessTime; | ||
75 | |||
76 | try | ||
77 | { | ||
78 | OpenDatabase(); | ||
79 | |||
80 | Migration m = new Migration(m_Connection, Assembly, "FSAssetStore"); | ||
81 | m.Update(); | ||
82 | } | ||
83 | catch (MySqlException e) | ||
84 | { | ||
85 | m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", e.Message.ToString()); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | public void Initialise() | ||
90 | { | ||
91 | throw new NotImplementedException(); | ||
92 | } | ||
93 | |||
94 | public void Dispose() { } | ||
95 | |||
96 | public string Name | ||
97 | { | ||
98 | get { return "MySQL FSAsset storage engine"; } | ||
99 | } | ||
100 | |||
101 | #endregion | ||
102 | |||
103 | private bool OpenDatabase() | ||
104 | { | ||
105 | try | ||
106 | { | ||
107 | m_Connection = new MySqlConnection(m_ConnectionString); | ||
108 | |||
109 | m_Connection.Open(); | ||
110 | } | ||
111 | catch (MySqlException e) | ||
112 | { | ||
113 | m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", | ||
114 | e.Message.ToString()); | ||
115 | |||
116 | return false; | ||
117 | } | ||
118 | |||
119 | return true; | ||
120 | } | ||
121 | |||
122 | private IDataReader ExecuteReader(MySqlCommand c) | ||
123 | { | ||
124 | IDataReader r = null; | ||
125 | MySqlConnection connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); | ||
126 | connection.Open(); | ||
127 | c.Connection = connection; | ||
128 | |||
129 | r = c.ExecuteReader(); | ||
130 | |||
131 | return r; | ||
132 | } | ||
133 | |||
134 | private void ExecuteNonQuery(MySqlCommand c) | ||
135 | { | ||
136 | lock (m_connLock) | ||
137 | { | ||
138 | bool errorSeen = false; | ||
139 | |||
140 | while (true) | ||
141 | { | ||
142 | try | ||
143 | { | ||
144 | c.ExecuteNonQuery(); | ||
145 | } | ||
146 | catch (MySqlException) | ||
147 | { | ||
148 | System.Threading.Thread.Sleep(500); | ||
149 | |||
150 | m_Connection.Close(); | ||
151 | m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); | ||
152 | m_Connection.Open(); | ||
153 | c.Connection = m_Connection; | ||
154 | |||
155 | if (!errorSeen) | ||
156 | { | ||
157 | errorSeen = true; | ||
158 | continue; | ||
159 | } | ||
160 | m_log.ErrorFormat("[FSASSETS] MySQL command: {0}", c.CommandText); | ||
161 | throw; | ||
162 | } | ||
163 | |||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | |||
169 | #region IFSAssetDataPlugin Members | ||
170 | |||
171 | public AssetMetadata Get(string id, out string hash) | ||
172 | { | ||
173 | hash = String.Empty; | ||
174 | |||
175 | MySqlCommand cmd = new MySqlCommand(); | ||
176 | |||
177 | cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, access_time, asset_flags from {0} where id = ?id", m_Table); | ||
178 | cmd.Parameters.AddWithValue("?id", id); | ||
179 | |||
180 | IDataReader reader = ExecuteReader(cmd); | ||
181 | |||
182 | if (!reader.Read()) | ||
183 | { | ||
184 | reader.Close(); | ||
185 | FreeCommand(cmd); | ||
186 | return null; | ||
187 | } | ||
188 | |||
189 | AssetMetadata meta = new AssetMetadata(); | ||
190 | |||
191 | hash = reader["hash"].ToString(); | ||
192 | |||
193 | meta.ID = id; | ||
194 | meta.FullID = new UUID(id); | ||
195 | |||
196 | meta.Name = reader["name"].ToString(); | ||
197 | meta.Description = reader["description"].ToString(); | ||
198 | meta.Type = (sbyte)Convert.ToInt32(reader["type"]); | ||
199 | meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); | ||
200 | meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); | ||
201 | meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]); | ||
202 | |||
203 | int AccessTime = Convert.ToInt32(reader["access_time"]); | ||
204 | |||
205 | reader.Close(); | ||
206 | |||
207 | UpdateAccessTime(AccessTime, cmd); | ||
208 | |||
209 | FreeCommand(cmd); | ||
210 | |||
211 | return meta; | ||
212 | } | ||
213 | |||
214 | private void UpdateAccessTime(int AccessTime, MySqlCommand cmd) | ||
215 | { | ||
216 | // Reduce DB work by only updating access time if asset hasn't recently been accessed | ||
217 | // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates" | ||
218 | if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates) | ||
219 | return; | ||
220 | |||
221 | cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table); | ||
222 | |||
223 | cmd.ExecuteNonQuery(); | ||
224 | } | ||
225 | |||
226 | protected void FreeCommand(MySqlCommand cmd) | ||
227 | { | ||
228 | MySqlConnection c = cmd.Connection; | ||
229 | cmd.Dispose(); | ||
230 | c.Close(); | ||
231 | c.Dispose(); | ||
232 | } | ||
233 | |||
234 | public bool Store(AssetMetadata meta, string hash) | ||
235 | { | ||
236 | try | ||
237 | { | ||
238 | string oldhash; | ||
239 | AssetMetadata existingAsset = Get(meta.ID, out oldhash); | ||
240 | |||
241 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
242 | |||
243 | cmd.Parameters.AddWithValue("?id", meta.ID); | ||
244 | cmd.Parameters.AddWithValue("?name", meta.Name); | ||
245 | cmd.Parameters.AddWithValue("?description", meta.Description); | ||
246 | cmd.Parameters.AddWithValue("?type", meta.Type.ToString()); | ||
247 | cmd.Parameters.AddWithValue("?hash", hash); | ||
248 | cmd.Parameters.AddWithValue("?asset_flags", meta.Flags); | ||
249 | |||
250 | if (existingAsset == null) | ||
251 | { | ||
252 | 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); | ||
253 | |||
254 | ExecuteNonQuery(cmd); | ||
255 | |||
256 | cmd.Dispose(); | ||
257 | |||
258 | return true; | ||
259 | } | ||
260 | |||
261 | //cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table); | ||
262 | |||
263 | //ExecuteNonQuery(cmd); | ||
264 | |||
265 | cmd.Dispose(); | ||
266 | return false; | ||
267 | } | ||
268 | catch(Exception e) | ||
269 | { | ||
270 | m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID); | ||
271 | m_log.Error(e.ToString()); | ||
272 | return false; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /// <summary> | ||
277 | /// Check if the assets exist in the database. | ||
278 | /// </summary> | ||
279 | /// <param name="uuids">The asset UUID's</param> | ||
280 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
281 | public bool[] AssetsExist(UUID[] uuids) | ||
282 | { | ||
283 | if (uuids.Length == 0) | ||
284 | return new bool[0]; | ||
285 | |||
286 | HashSet<UUID> exists = new HashSet<UUID>(); | ||
287 | |||
288 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
289 | string sql = string.Format("select id from {1} where id in ({0})", ids, m_Table); | ||
290 | |||
291 | using (MySqlCommand cmd = m_Connection.CreateCommand()) | ||
292 | { | ||
293 | cmd.CommandText = sql; | ||
294 | |||
295 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
296 | { | ||
297 | while (dbReader.Read()) | ||
298 | { | ||
299 | UUID id = DBGuid.FromDB(dbReader["ID"]); | ||
300 | exists.Add(id); | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | |||
305 | bool[] results = new bool[uuids.Length]; | ||
306 | for (int i = 0; i < uuids.Length; i++) | ||
307 | results[i] = exists.Contains(uuids[i]); | ||
308 | return results; | ||
309 | } | ||
310 | |||
311 | public int Count() | ||
312 | { | ||
313 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
314 | |||
315 | cmd.CommandText = String.Format("select count(*) as count from {0}", m_Table); | ||
316 | |||
317 | IDataReader reader = ExecuteReader(cmd); | ||
318 | |||
319 | reader.Read(); | ||
320 | |||
321 | int count = Convert.ToInt32(reader["count"]); | ||
322 | |||
323 | reader.Close(); | ||
324 | FreeCommand(cmd); | ||
325 | |||
326 | return count; | ||
327 | } | ||
328 | |||
329 | public bool Delete(string id) | ||
330 | { | ||
331 | using (MySqlCommand cmd = m_Connection.CreateCommand()) | ||
332 | { | ||
333 | cmd.CommandText = String.Format("delete from {0} where id = ?id", m_Table); | ||
334 | |||
335 | cmd.Parameters.AddWithValue("?id", id); | ||
336 | |||
337 | ExecuteNonQuery(cmd); | ||
338 | } | ||
339 | |||
340 | return true; | ||
341 | } | ||
342 | |||
343 | public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store) | ||
344 | { | ||
345 | MySqlConnection importConn; | ||
346 | |||
347 | try | ||
348 | { | ||
349 | importConn = new MySqlConnection(conn); | ||
350 | |||
351 | importConn.Open(); | ||
352 | } | ||
353 | catch (MySqlException e) | ||
354 | { | ||
355 | m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", | ||
356 | e.Message.ToString()); | ||
357 | |||
358 | return; | ||
359 | } | ||
360 | |||
361 | int imported = 0; | ||
362 | |||
363 | MySqlCommand cmd = importConn.CreateCommand(); | ||
364 | |||
365 | string limit = String.Empty; | ||
366 | if (count != -1) | ||
367 | { | ||
368 | limit = String.Format(" limit {0},{1}", start, count); | ||
369 | } | ||
370 | |||
371 | cmd.CommandText = String.Format("select * from {0}{1}", table, limit); | ||
372 | |||
373 | MainConsole.Instance.Output("Querying database"); | ||
374 | IDataReader reader = cmd.ExecuteReader(); | ||
375 | |||
376 | MainConsole.Instance.Output("Reading data"); | ||
377 | |||
378 | while (reader.Read()) | ||
379 | { | ||
380 | if ((imported % 100) == 0) | ||
381 | { | ||
382 | MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); | ||
383 | } | ||
384 | |||
385 | AssetBase asset = new AssetBase(); | ||
386 | AssetMetadata meta = new AssetMetadata(); | ||
387 | |||
388 | meta.ID = reader["id"].ToString(); | ||
389 | meta.FullID = new UUID(meta.ID); | ||
390 | |||
391 | meta.Name = reader["name"].ToString(); | ||
392 | meta.Description = reader["description"].ToString(); | ||
393 | meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); | ||
394 | meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); | ||
395 | meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); | ||
396 | |||
397 | asset.Metadata = meta; | ||
398 | asset.Data = (byte[])reader["data"]; | ||
399 | |||
400 | store(asset, force); | ||
401 | |||
402 | imported++; | ||
403 | } | ||
404 | |||
405 | reader.Close(); | ||
406 | cmd.Dispose(); | ||
407 | importConn.Close(); | ||
408 | |||
409 | MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); | ||
410 | } | ||
411 | |||
412 | #endregion | ||
413 | } | ||
414 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs new file mode 100644 index 0000000..5820a90 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLFramework.cs | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using MySql.Data.MySqlClient; | ||
35 | |||
36 | namespace OpenSim.Data.MySQL | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// A database interface class to a user profile storage system | ||
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; | ||
48 | |||
49 | protected MySqlFramework(string connectionString) | ||
50 | { | ||
51 | m_connectionString = connectionString; | ||
52 | } | ||
53 | |||
54 | protected int ExecuteNonQuery(MySqlCommand cmd) | ||
55 | { | ||
56 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
57 | { | ||
58 | dbcon.Open(); | ||
59 | cmd.Connection = dbcon; | ||
60 | |||
61 | try | ||
62 | { | ||
63 | return cmd.ExecuteNonQuery(); | ||
64 | } | ||
65 | catch (Exception e) | ||
66 | { | ||
67 | m_log.Error(e.Message, e); | ||
68 | return 0; | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | } \ No newline at end of file | ||
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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using MySql.Data.MySqlClient; | ||
35 | |||
36 | namespace 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..35fa89f --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | |||
@@ -0,0 +1,365 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using MySql.Data.MySqlClient; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Region.Framework.Interfaces; | ||
37 | |||
38 | namespace 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(string connectionString, | ||
57 | string realm, string storeName) : base(connectionString) | ||
58 | { | ||
59 | m_Realm = realm; | ||
60 | m_connectionString = connectionString; | ||
61 | |||
62 | if (storeName != String.Empty) | ||
63 | { | ||
64 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
65 | { | ||
66 | dbcon.Open(); | ||
67 | Migration m = new Migration(dbcon, Assembly, storeName); | ||
68 | m.Update(); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | Type t = typeof(T); | ||
73 | FieldInfo[] fields = t.GetFields(BindingFlags.Public | | ||
74 | BindingFlags.Instance | | ||
75 | BindingFlags.DeclaredOnly); | ||
76 | |||
77 | if (fields.Length == 0) | ||
78 | return; | ||
79 | |||
80 | foreach (FieldInfo f in fields) | ||
81 | { | ||
82 | if (f.Name != "Data") | ||
83 | m_Fields[f.Name] = f; | ||
84 | else | ||
85 | m_DataField = f; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | private void CheckColumnNames(IDataReader reader) | ||
90 | { | ||
91 | if (m_ColumnNames != null) | ||
92 | return; | ||
93 | |||
94 | List<string> columnNames = new List<string>(); | ||
95 | |||
96 | DataTable schemaTable = reader.GetSchemaTable(); | ||
97 | foreach (DataRow row in schemaTable.Rows) | ||
98 | { | ||
99 | if (row["ColumnName"] != null && | ||
100 | (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) | ||
101 | columnNames.Add(row["ColumnName"].ToString()); | ||
102 | } | ||
103 | |||
104 | m_ColumnNames = columnNames; | ||
105 | } | ||
106 | |||
107 | public virtual T[] Get(string field, string key) | ||
108 | { | ||
109 | return Get(new string[] { field }, new string[] { key }); | ||
110 | } | ||
111 | |||
112 | public virtual T[] Get(string[] fields, string[] keys) | ||
113 | { | ||
114 | if (fields.Length != keys.Length) | ||
115 | return new T[0]; | ||
116 | |||
117 | List<string> terms = new List<string>(); | ||
118 | |||
119 | using (MySqlCommand cmd = new MySqlCommand()) | ||
120 | { | ||
121 | for (int i = 0 ; i < fields.Length ; i++) | ||
122 | { | ||
123 | cmd.Parameters.AddWithValue(fields[i], keys[i]); | ||
124 | terms.Add("`" + fields[i] + "` = ?" + fields[i]); | ||
125 | } | ||
126 | |||
127 | string where = String.Join(" and ", terms.ToArray()); | ||
128 | |||
129 | string query = String.Format("select * from {0} where {1}", | ||
130 | m_Realm, where); | ||
131 | |||
132 | cmd.CommandText = query; | ||
133 | |||
134 | return DoQuery(cmd); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | protected T[] DoQuery(MySqlCommand cmd) | ||
139 | { | ||
140 | List<T> result = new List<T>(); | ||
141 | |||
142 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
143 | { | ||
144 | dbcon.Open(); | ||
145 | cmd.Connection = dbcon; | ||
146 | |||
147 | using (IDataReader reader = cmd.ExecuteReader()) | ||
148 | { | ||
149 | if (reader == null) | ||
150 | return new T[0]; | ||
151 | |||
152 | CheckColumnNames(reader); | ||
153 | |||
154 | while (reader.Read()) | ||
155 | { | ||
156 | T row = new T(); | ||
157 | |||
158 | foreach (string name in m_Fields.Keys) | ||
159 | { | ||
160 | if (reader[name] is DBNull) | ||
161 | { | ||
162 | continue; | ||
163 | } | ||
164 | if (m_Fields[name].FieldType == typeof(bool)) | ||
165 | { | ||
166 | int v = Convert.ToInt32(reader[name]); | ||
167 | m_Fields[name].SetValue(row, v != 0 ? true : false); | ||
168 | } | ||
169 | else if (m_Fields[name].FieldType == typeof(UUID)) | ||
170 | { | ||
171 | m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); | ||
172 | } | ||
173 | else if (m_Fields[name].FieldType == typeof(int)) | ||
174 | { | ||
175 | int v = Convert.ToInt32(reader[name]); | ||
176 | m_Fields[name].SetValue(row, v); | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | m_Fields[name].SetValue(row, reader[name]); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | if (m_DataField != null) | ||
185 | { | ||
186 | Dictionary<string, string> data = | ||
187 | new Dictionary<string, string>(); | ||
188 | |||
189 | foreach (string col in m_ColumnNames) | ||
190 | { | ||
191 | data[col] = reader[col].ToString(); | ||
192 | if (data[col] == null) | ||
193 | data[col] = String.Empty; | ||
194 | } | ||
195 | |||
196 | m_DataField.SetValue(row, data); | ||
197 | } | ||
198 | |||
199 | result.Add(row); | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | |||
204 | return result.ToArray(); | ||
205 | } | ||
206 | |||
207 | public virtual T[] Get(string where) | ||
208 | { | ||
209 | using (MySqlCommand cmd = new MySqlCommand()) | ||
210 | { | ||
211 | string query = String.Format("select * from {0} where {1}", | ||
212 | m_Realm, where); | ||
213 | |||
214 | cmd.CommandText = query; | ||
215 | |||
216 | return DoQuery(cmd); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | public virtual bool Store(T row) | ||
221 | { | ||
222 | // m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked"); | ||
223 | |||
224 | using (MySqlCommand cmd = new MySqlCommand()) | ||
225 | { | ||
226 | string query = ""; | ||
227 | List<String> names = new List<String>(); | ||
228 | List<String> values = new List<String>(); | ||
229 | |||
230 | foreach (FieldInfo fi in m_Fields.Values) | ||
231 | { | ||
232 | names.Add(fi.Name); | ||
233 | values.Add("?" + fi.Name); | ||
234 | |||
235 | // Temporarily return more information about what field is unexpectedly null for | ||
236 | // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the | ||
237 | // InventoryTransferModule or we may be required to substitute a DBNull here. | ||
238 | if (fi.GetValue(row) == null) | ||
239 | throw new NullReferenceException( | ||
240 | string.Format( | ||
241 | "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", | ||
242 | fi.Name, row)); | ||
243 | |||
244 | cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); | ||
245 | } | ||
246 | |||
247 | if (m_DataField != null) | ||
248 | { | ||
249 | Dictionary<string, string> data = | ||
250 | (Dictionary<string, string>)m_DataField.GetValue(row); | ||
251 | |||
252 | foreach (KeyValuePair<string, string> kvp in data) | ||
253 | { | ||
254 | names.Add(kvp.Key); | ||
255 | values.Add("?" + kvp.Key); | ||
256 | cmd.Parameters.AddWithValue("?" + kvp.Key, kvp.Value); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; | ||
261 | |||
262 | cmd.CommandText = query; | ||
263 | |||
264 | if (ExecuteNonQuery(cmd) > 0) | ||
265 | return true; | ||
266 | |||
267 | return false; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | public virtual bool Delete(string field, string key) | ||
272 | { | ||
273 | return Delete(new string[] { field }, new string[] { key }); | ||
274 | } | ||
275 | |||
276 | public virtual bool Delete(string[] fields, string[] keys) | ||
277 | { | ||
278 | // m_log.DebugFormat( | ||
279 | // "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}", | ||
280 | // string.Join(",", fields), string.Join(",", keys)); | ||
281 | |||
282 | if (fields.Length != keys.Length) | ||
283 | return false; | ||
284 | |||
285 | List<string> terms = new List<string>(); | ||
286 | |||
287 | using (MySqlCommand cmd = new MySqlCommand()) | ||
288 | { | ||
289 | for (int i = 0 ; i < fields.Length ; i++) | ||
290 | { | ||
291 | cmd.Parameters.AddWithValue(fields[i], keys[i]); | ||
292 | terms.Add("`" + fields[i] + "` = ?" + fields[i]); | ||
293 | } | ||
294 | |||
295 | string where = String.Join(" and ", terms.ToArray()); | ||
296 | |||
297 | string query = String.Format("delete from {0} where {1}", m_Realm, where); | ||
298 | |||
299 | cmd.CommandText = query; | ||
300 | |||
301 | return ExecuteNonQuery(cmd) > 0; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | public long GetCount(string field, string key) | ||
306 | { | ||
307 | return GetCount(new string[] { field }, new string[] { key }); | ||
308 | } | ||
309 | |||
310 | public long GetCount(string[] fields, string[] keys) | ||
311 | { | ||
312 | if (fields.Length != keys.Length) | ||
313 | return 0; | ||
314 | |||
315 | List<string> terms = new List<string>(); | ||
316 | |||
317 | using (MySqlCommand cmd = new MySqlCommand()) | ||
318 | { | ||
319 | for (int i = 0; i < fields.Length; i++) | ||
320 | { | ||
321 | cmd.Parameters.AddWithValue(fields[i], keys[i]); | ||
322 | terms.Add("`" + fields[i] + "` = ?" + fields[i]); | ||
323 | } | ||
324 | |||
325 | string where = String.Join(" and ", terms.ToArray()); | ||
326 | |||
327 | string query = String.Format("select count(*) from {0} where {1}", | ||
328 | m_Realm, where); | ||
329 | |||
330 | cmd.CommandText = query; | ||
331 | |||
332 | Object result = DoQueryScalar(cmd); | ||
333 | |||
334 | return Convert.ToInt64(result); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | public long GetCount(string where) | ||
339 | { | ||
340 | using (MySqlCommand cmd = new MySqlCommand()) | ||
341 | { | ||
342 | string query = String.Format("select count(*) from {0} where {1}", | ||
343 | m_Realm, where); | ||
344 | |||
345 | cmd.CommandText = query; | ||
346 | |||
347 | object result = DoQueryScalar(cmd); | ||
348 | |||
349 | return Convert.ToInt64(result); | ||
350 | } | ||
351 | } | ||
352 | |||
353 | public object DoQueryScalar(MySqlCommand cmd) | ||
354 | { | ||
355 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
356 | { | ||
357 | dbcon.Open(); | ||
358 | cmd.Connection = dbcon; | ||
359 | |||
360 | return cmd.ExecuteScalar(); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | } | ||
365 | } \ No newline at end of file | ||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | |||
38 | namespace 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..afa499e --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLGroupsData.cs | |||
@@ -0,0 +1,484 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Data.MySQL; | ||
35 | |||
36 | using OpenMetaverse; | ||
37 | using MySql.Data.MySqlClient; | ||
38 | |||
39 | namespace 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 < ?tstamp", m_Realm); | ||
435 | cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old | ||
436 | |||
437 | ExecuteNonQuery(cmd); | ||
438 | } | ||
439 | |||
440 | } | ||
441 | } | ||
442 | |||
443 | public class MySqlGroupsNoticesHandler : MySQLGenericTableHandler<NoticeData> | ||
444 | { | ||
445 | protected override Assembly Assembly | ||
446 | { | ||
447 | // WARNING! Moving migrations to this assembly!!! | ||
448 | get { return GetType().Assembly; } | ||
449 | } | ||
450 | |||
451 | public MySqlGroupsNoticesHandler(string connectionString, string realm) | ||
452 | : base(connectionString, realm, string.Empty) | ||
453 | { | ||
454 | } | ||
455 | |||
456 | public void DeleteOld() | ||
457 | { | ||
458 | uint now = (uint)Util.UnixTimeSinceEpoch(); | ||
459 | |||
460 | using (MySqlCommand cmd = new MySqlCommand()) | ||
461 | { | ||
462 | cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm); | ||
463 | cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old | ||
464 | |||
465 | ExecuteNonQuery(cmd); | ||
466 | } | ||
467 | |||
468 | } | ||
469 | } | ||
470 | |||
471 | public class MySqlGroupsPrincipalsHandler : MySQLGenericTableHandler<PrincipalData> | ||
472 | { | ||
473 | protected override Assembly Assembly | ||
474 | { | ||
475 | // WARNING! Moving migrations to this assembly!!! | ||
476 | get { return GetType().Assembly; } | ||
477 | } | ||
478 | |||
479 | public MySqlGroupsPrincipalsHandler(string connectionString, string realm) | ||
480 | : base(connectionString, realm, string.Empty) | ||
481 | { | ||
482 | } | ||
483 | } | ||
484 | } | ||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | |||
38 | namespace 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..e9b10f3 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs | |||
@@ -0,0 +1,902 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using MySql.Data.MySqlClient; | ||
33 | using OpenMetaverse; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Data; | ||
36 | |||
37 | namespace 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 | } | ||
82 | } | ||
83 | |||
84 | /// <summary> | ||
85 | /// The name of this DB provider | ||
86 | /// </summary> | ||
87 | /// <returns>Name of DB provider</returns> | ||
88 | public string Name | ||
89 | { | ||
90 | get { return "MySQL Inventory Data Interface"; } | ||
91 | } | ||
92 | |||
93 | /// <summary> | ||
94 | /// Closes this DB provider | ||
95 | /// </summary> | ||
96 | /// <remarks>do nothing</remarks> | ||
97 | public void Dispose() | ||
98 | { | ||
99 | // Do nothing. | ||
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// Returns a list of items in a specified folder | ||
104 | /// </summary> | ||
105 | /// <param name="folderID">The folder to search</param> | ||
106 | /// <returns>A list containing inventory items</returns> | ||
107 | public List<InventoryItemBase> getInventoryInFolder(UUID folderID) | ||
108 | { | ||
109 | try | ||
110 | { | ||
111 | lock (m_dbLock) | ||
112 | { | ||
113 | List<InventoryItemBase> items = new List<InventoryItemBase>(); | ||
114 | |||
115 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
116 | { | ||
117 | dbcon.Open(); | ||
118 | |||
119 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", dbcon)) | ||
120 | { | ||
121 | result.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
122 | |||
123 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
124 | { | ||
125 | while (reader.Read()) | ||
126 | { | ||
127 | // A null item (because something went wrong) breaks everything in the folder | ||
128 | InventoryItemBase item = readInventoryItem(reader); | ||
129 | if (item != null) | ||
130 | items.Add(item); | ||
131 | } | ||
132 | |||
133 | return items; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | catch (Exception e) | ||
140 | { | ||
141 | m_log.Error(e.Message, e); | ||
142 | return null; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /// <summary> | ||
147 | /// Returns a list of the root folders within a users inventory | ||
148 | /// </summary> | ||
149 | /// <param name="user">The user whose inventory is to be searched</param> | ||
150 | /// <returns>A list of folder objects</returns> | ||
151 | public List<InventoryFolderBase> getUserRootFolders(UUID user) | ||
152 | { | ||
153 | try | ||
154 | { | ||
155 | lock (m_dbLock) | ||
156 | { | ||
157 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
158 | { | ||
159 | dbcon.Open(); | ||
160 | |||
161 | using (MySqlCommand result = new MySqlCommand( | ||
162 | "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon)) | ||
163 | { | ||
164 | result.Parameters.AddWithValue("?uuid", user.ToString()); | ||
165 | result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); | ||
166 | |||
167 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
168 | { | ||
169 | List<InventoryFolderBase> items = new List<InventoryFolderBase>(); | ||
170 | while (reader.Read()) | ||
171 | items.Add(readInventoryFolder(reader)); | ||
172 | |||
173 | return items; | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | catch (Exception e) | ||
180 | { | ||
181 | m_log.Error(e.Message, e); | ||
182 | return null; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | |||
187 | /// <summary> | ||
188 | /// see <see cref="InventoryItemBase.getUserRootFolder"/> | ||
189 | /// </summary> | ||
190 | /// <param name="user">The user UUID</param> | ||
191 | /// <returns></returns> | ||
192 | public InventoryFolderBase getUserRootFolder(UUID user) | ||
193 | { | ||
194 | try | ||
195 | { | ||
196 | lock (m_dbLock) | ||
197 | { | ||
198 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
199 | { | ||
200 | dbcon.Open(); | ||
201 | |||
202 | using (MySqlCommand result = new MySqlCommand( | ||
203 | "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon)) | ||
204 | { | ||
205 | result.Parameters.AddWithValue("?uuid", user.ToString()); | ||
206 | result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); | ||
207 | |||
208 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
209 | { | ||
210 | List<InventoryFolderBase> items = new List<InventoryFolderBase>(); | ||
211 | while (reader.Read()) | ||
212 | items.Add(readInventoryFolder(reader)); | ||
213 | |||
214 | InventoryFolderBase rootFolder = null; | ||
215 | |||
216 | // There should only ever be one root folder for a user. However, if there's more | ||
217 | // than one we'll simply use the first one rather than failing. It would be even | ||
218 | // nicer to print some message to this effect, but this feels like it's too low a | ||
219 | // to put such a message out, and it's too minor right now to spare the time to | ||
220 | // suitably refactor. | ||
221 | if (items.Count > 0) | ||
222 | rootFolder = items[0]; | ||
223 | |||
224 | return rootFolder; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | catch (Exception e) | ||
231 | { | ||
232 | m_log.Error(e.Message, e); | ||
233 | return null; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | /// <summary> | ||
238 | /// Return a list of folders in a users inventory contained within the specified folder. | ||
239 | /// This method is only used in tests - in normal operation the user always have one, | ||
240 | /// and only one, root folder. | ||
241 | /// </summary> | ||
242 | /// <param name="parentID">The folder to search</param> | ||
243 | /// <returns>A list of inventory folders</returns> | ||
244 | public List<InventoryFolderBase> getInventoryFolders(UUID parentID) | ||
245 | { | ||
246 | try | ||
247 | { | ||
248 | lock (m_dbLock) | ||
249 | { | ||
250 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
251 | { | ||
252 | dbcon.Open(); | ||
253 | |||
254 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", dbcon)) | ||
255 | { | ||
256 | result.Parameters.AddWithValue("?uuid", parentID.ToString()); | ||
257 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
258 | { | ||
259 | List<InventoryFolderBase> items = new List<InventoryFolderBase>(); | ||
260 | |||
261 | while (reader.Read()) | ||
262 | items.Add(readInventoryFolder(reader)); | ||
263 | |||
264 | return items; | ||
265 | } | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | catch (Exception e) | ||
271 | { | ||
272 | m_log.Error(e.Message, e); | ||
273 | return null; | ||
274 | } | ||
275 | } | ||
276 | |||
277 | /// <summary> | ||
278 | /// Reads a one item from an SQL result | ||
279 | /// </summary> | ||
280 | /// <param name="reader">The SQL Result</param> | ||
281 | /// <returns>the item read</returns> | ||
282 | private static InventoryItemBase readInventoryItem(MySqlDataReader reader) | ||
283 | { | ||
284 | try | ||
285 | { | ||
286 | InventoryItemBase item = new InventoryItemBase(); | ||
287 | |||
288 | // 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. | ||
289 | // (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero) | ||
290 | item.CreatorId = reader["creatorID"].ToString(); | ||
291 | |||
292 | // Be a bit safer in parsing these because the | ||
293 | // database doesn't enforce them to be not null, and | ||
294 | // the inventory still works if these are weird in the | ||
295 | // db | ||
296 | |||
297 | // (Empty is Ok, but "weird" will throw!) | ||
298 | item.Owner = DBGuid.FromDB(reader["avatarID"]); | ||
299 | item.GroupID = DBGuid.FromDB(reader["groupID"]); | ||
300 | |||
301 | // Rest of the parsing. If these UUID's fail, we're dead anyway | ||
302 | item.ID = DBGuid.FromDB(reader["inventoryID"]); | ||
303 | item.AssetID = DBGuid.FromDB(reader["assetID"]); | ||
304 | item.AssetType = (int) reader["assetType"]; | ||
305 | item.Folder = DBGuid.FromDB(reader["parentFolderID"]); | ||
306 | item.Name = (string)(reader["inventoryName"] ?? String.Empty); | ||
307 | item.Description = (string)(reader["inventoryDescription"] ?? String.Empty); | ||
308 | item.NextPermissions = (uint) reader["inventoryNextPermissions"]; | ||
309 | item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"]; | ||
310 | item.InvType = (int) reader["invType"]; | ||
311 | item.BasePermissions = (uint) reader["inventoryBasePermissions"]; | ||
312 | item.EveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"]; | ||
313 | item.GroupPermissions = (uint) reader["inventoryGroupPermissions"]; | ||
314 | item.SalePrice = (int) reader["salePrice"]; | ||
315 | item.SaleType = unchecked((byte)(Convert.ToSByte(reader["saleType"]))); | ||
316 | item.CreationDate = (int) reader["creationDate"]; | ||
317 | item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]); | ||
318 | item.Flags = (uint) reader["flags"]; | ||
319 | |||
320 | return item; | ||
321 | } | ||
322 | catch (MySqlException e) | ||
323 | { | ||
324 | m_log.Error(e.ToString()); | ||
325 | } | ||
326 | |||
327 | return null; | ||
328 | } | ||
329 | |||
330 | /// <summary> | ||
331 | /// Returns a specified inventory item | ||
332 | /// </summary> | ||
333 | /// <param name="item">The item to return</param> | ||
334 | /// <returns>An inventory item</returns> | ||
335 | public InventoryItemBase getInventoryItem(UUID itemID) | ||
336 | { | ||
337 | try | ||
338 | { | ||
339 | lock (m_dbLock) | ||
340 | { | ||
341 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
342 | { | ||
343 | dbcon.Open(); | ||
344 | |||
345 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", dbcon)) | ||
346 | { | ||
347 | result.Parameters.AddWithValue("?uuid", itemID.ToString()); | ||
348 | |||
349 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
350 | { | ||
351 | InventoryItemBase item = null; | ||
352 | if (reader.Read()) | ||
353 | item = readInventoryItem(reader); | ||
354 | |||
355 | return item; | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | } | ||
361 | catch (Exception e) | ||
362 | { | ||
363 | m_log.Error(e.Message, e); | ||
364 | } | ||
365 | return null; | ||
366 | } | ||
367 | |||
368 | /// <summary> | ||
369 | /// Reads a list of inventory folders returned by a query. | ||
370 | /// </summary> | ||
371 | /// <param name="reader">A MySQL Data Reader</param> | ||
372 | /// <returns>A List containing inventory folders</returns> | ||
373 | protected static InventoryFolderBase readInventoryFolder(MySqlDataReader reader) | ||
374 | { | ||
375 | try | ||
376 | { | ||
377 | InventoryFolderBase folder = new InventoryFolderBase(); | ||
378 | folder.Owner = DBGuid.FromDB(reader["agentID"]); | ||
379 | folder.ParentID = DBGuid.FromDB(reader["parentFolderID"]); | ||
380 | folder.ID = DBGuid.FromDB(reader["folderID"]); | ||
381 | folder.Name = (string) reader["folderName"]; | ||
382 | folder.Type = (short) reader["type"]; | ||
383 | folder.Version = (ushort) ((int) reader["version"]); | ||
384 | return folder; | ||
385 | } | ||
386 | catch (Exception e) | ||
387 | { | ||
388 | m_log.Error(e.Message, e); | ||
389 | } | ||
390 | |||
391 | return null; | ||
392 | } | ||
393 | |||
394 | |||
395 | /// <summary> | ||
396 | /// Returns a specified inventory folder | ||
397 | /// </summary> | ||
398 | /// <param name="folderID">The folder to return</param> | ||
399 | /// <returns>A folder class</returns> | ||
400 | public InventoryFolderBase getInventoryFolder(UUID folderID) | ||
401 | { | ||
402 | try | ||
403 | { | ||
404 | lock (m_dbLock) | ||
405 | { | ||
406 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
407 | { | ||
408 | dbcon.Open(); | ||
409 | |||
410 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon)) | ||
411 | { | ||
412 | result.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
413 | |||
414 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
415 | { | ||
416 | InventoryFolderBase folder = null; | ||
417 | if (reader.Read()) | ||
418 | folder = readInventoryFolder(reader); | ||
419 | |||
420 | return folder; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | catch (Exception e) | ||
427 | { | ||
428 | m_log.Error(e.Message, e); | ||
429 | return null; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | /// <summary> | ||
434 | /// Adds a specified item to the database | ||
435 | /// </summary> | ||
436 | /// <param name="item">The inventory item</param> | ||
437 | public void addInventoryItem(InventoryItemBase item) | ||
438 | { | ||
439 | string sql = | ||
440 | "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName" | ||
441 | + ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType" | ||
442 | + ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, inventoryGroupPermissions, salePrice, saleType" | ||
443 | + ", creationDate, groupID, groupOwned, flags) VALUES "; | ||
444 | sql += | ||
445 | "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription" | ||
446 | + ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID" | ||
447 | + ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?inventoryGroupPermissions, ?salePrice, ?saleType, ?creationDate" | ||
448 | + ", ?groupID, ?groupOwned, ?flags)"; | ||
449 | |||
450 | string itemName = item.Name; | ||
451 | if (item.Name.Length > 64) | ||
452 | { | ||
453 | itemName = item.Name.Substring(0, 64); | ||
454 | m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item"); | ||
455 | } | ||
456 | |||
457 | string itemDesc = item.Description; | ||
458 | if (item.Description.Length > 128) | ||
459 | { | ||
460 | itemDesc = item.Description.Substring(0, 128); | ||
461 | m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length + " to " + itemDesc.Length + " characters on add item"); | ||
462 | } | ||
463 | |||
464 | try | ||
465 | { | ||
466 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
467 | { | ||
468 | dbcon.Open(); | ||
469 | |||
470 | using (MySqlCommand result = new MySqlCommand(sql, dbcon)) | ||
471 | { | ||
472 | result.Parameters.AddWithValue("?inventoryID", item.ID.ToString()); | ||
473 | result.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); | ||
474 | result.Parameters.AddWithValue("?assetType", item.AssetType.ToString()); | ||
475 | result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString()); | ||
476 | result.Parameters.AddWithValue("?avatarID", item.Owner.ToString()); | ||
477 | result.Parameters.AddWithValue("?inventoryName", itemName); | ||
478 | result.Parameters.AddWithValue("?inventoryDescription", itemDesc); | ||
479 | result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString()); | ||
480 | result.Parameters.AddWithValue("?inventoryCurrentPermissions", | ||
481 | item.CurrentPermissions.ToString()); | ||
482 | result.Parameters.AddWithValue("?invType", item.InvType); | ||
483 | result.Parameters.AddWithValue("?creatorID", item.CreatorId); | ||
484 | result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); | ||
485 | result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); | ||
486 | result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); | ||
487 | result.Parameters.AddWithValue("?salePrice", item.SalePrice); | ||
488 | result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType)); | ||
489 | result.Parameters.AddWithValue("?creationDate", item.CreationDate); | ||
490 | result.Parameters.AddWithValue("?groupID", item.GroupID); | ||
491 | result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); | ||
492 | result.Parameters.AddWithValue("?flags", item.Flags); | ||
493 | |||
494 | lock (m_dbLock) | ||
495 | result.ExecuteNonQuery(); | ||
496 | |||
497 | result.Dispose(); | ||
498 | } | ||
499 | |||
500 | using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon)) | ||
501 | { | ||
502 | result.Parameters.AddWithValue("?folderID", item.Folder.ToString()); | ||
503 | |||
504 | lock (m_dbLock) | ||
505 | result.ExecuteNonQuery(); | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | catch (MySqlException e) | ||
510 | { | ||
511 | m_log.Error(e.ToString()); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /// <summary> | ||
516 | /// Updates the specified inventory item | ||
517 | /// </summary> | ||
518 | /// <param name="item">Inventory item to update</param> | ||
519 | public void updateInventoryItem(InventoryItemBase item) | ||
520 | { | ||
521 | addInventoryItem(item); | ||
522 | } | ||
523 | |||
524 | /// <summary> | ||
525 | /// Detele the specified inventory item | ||
526 | /// </summary> | ||
527 | /// <param name="item">The inventory item UUID to delete</param> | ||
528 | public void deleteInventoryItem(UUID itemID) | ||
529 | { | ||
530 | try | ||
531 | { | ||
532 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
533 | { | ||
534 | dbcon.Open(); | ||
535 | |||
536 | using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon)) | ||
537 | { | ||
538 | cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); | ||
539 | |||
540 | lock (m_dbLock) | ||
541 | cmd.ExecuteNonQuery(); | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | catch (MySqlException e) | ||
546 | { | ||
547 | m_log.Error(e.Message, e); | ||
548 | } | ||
549 | } | ||
550 | |||
551 | public InventoryItemBase queryInventoryItem(UUID itemID) | ||
552 | { | ||
553 | return getInventoryItem(itemID); | ||
554 | } | ||
555 | |||
556 | public InventoryFolderBase queryInventoryFolder(UUID folderID) | ||
557 | { | ||
558 | return getInventoryFolder(folderID); | ||
559 | } | ||
560 | |||
561 | /// <summary> | ||
562 | /// Creates a new inventory folder | ||
563 | /// </summary> | ||
564 | /// <param name="folder">Folder to create</param> | ||
565 | public void addInventoryFolder(InventoryFolderBase folder) | ||
566 | { | ||
567 | string sql = | ||
568 | "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES "; | ||
569 | sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)"; | ||
570 | |||
571 | string folderName = folder.Name; | ||
572 | if (folderName.Length > 64) | ||
573 | { | ||
574 | folderName = folderName.Substring(0, 64); | ||
575 | m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length + " to " + folderName.Length + " characters on add folder"); | ||
576 | } | ||
577 | |||
578 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
579 | { | ||
580 | dbcon.Open(); | ||
581 | |||
582 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
583 | { | ||
584 | cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); | ||
585 | cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString()); | ||
586 | cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); | ||
587 | cmd.Parameters.AddWithValue("?folderName", folderName); | ||
588 | cmd.Parameters.AddWithValue("?type", folder.Type); | ||
589 | cmd.Parameters.AddWithValue("?version", folder.Version); | ||
590 | |||
591 | try | ||
592 | { | ||
593 | lock (m_dbLock) | ||
594 | { | ||
595 | cmd.ExecuteNonQuery(); | ||
596 | } | ||
597 | } | ||
598 | catch (Exception e) | ||
599 | { | ||
600 | m_log.Error(e.ToString()); | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /// <summary> | ||
607 | /// Updates an inventory folder | ||
608 | /// </summary> | ||
609 | /// <param name="folder">Folder to update</param> | ||
610 | public void updateInventoryFolder(InventoryFolderBase folder) | ||
611 | { | ||
612 | addInventoryFolder(folder); | ||
613 | } | ||
614 | |||
615 | /// <summary> | ||
616 | /// Move an inventory folder | ||
617 | /// </summary> | ||
618 | /// <param name="folder">Folder to move</param> | ||
619 | /// <remarks>UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID</remarks> | ||
620 | public void moveInventoryFolder(InventoryFolderBase folder) | ||
621 | { | ||
622 | string sql = | ||
623 | "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID"; | ||
624 | |||
625 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
626 | { | ||
627 | dbcon.Open(); | ||
628 | |||
629 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
630 | { | ||
631 | cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); | ||
632 | cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); | ||
633 | |||
634 | try | ||
635 | { | ||
636 | lock (m_dbLock) | ||
637 | { | ||
638 | cmd.ExecuteNonQuery(); | ||
639 | } | ||
640 | } | ||
641 | catch (Exception e) | ||
642 | { | ||
643 | m_log.Error(e.ToString()); | ||
644 | } | ||
645 | } | ||
646 | } | ||
647 | } | ||
648 | |||
649 | /// <summary> | ||
650 | /// Append a list of all the child folders of a parent folder | ||
651 | /// </summary> | ||
652 | /// <param name="folders">list where folders will be appended</param> | ||
653 | /// <param name="parentID">ID of parent</param> | ||
654 | protected void getInventoryFolders(ref List<InventoryFolderBase> folders, UUID parentID) | ||
655 | { | ||
656 | List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID); | ||
657 | |||
658 | foreach (InventoryFolderBase f in subfolderList) | ||
659 | folders.Add(f); | ||
660 | } | ||
661 | |||
662 | |||
663 | /// <summary> | ||
664 | /// See IInventoryDataPlugin | ||
665 | /// </summary> | ||
666 | /// <param name="parentID"></param> | ||
667 | /// <returns></returns> | ||
668 | public List<InventoryFolderBase> getFolderHierarchy(UUID parentID) | ||
669 | { | ||
670 | /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one | ||
671 | * - We will only need to hit the database twice instead of n times. | ||
672 | * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned | ||
673 | * by the same person, each user only has 1 inventory heirarchy | ||
674 | * - The returned list is not ordered, instead of breadth-first ordered | ||
675 | There are basically 2 usage cases for getFolderHeirarchy: | ||
676 | 1) Getting the user's entire inventory heirarchy when they log in | ||
677 | 2) Finding a subfolder heirarchy to delete when emptying the trash. | ||
678 | This implementation will pull all inventory folders from the database, and then prune away any folder that | ||
679 | is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the | ||
680 | database than to make n requests. This pays off only if requested heirarchy is large. | ||
681 | By making this choice, we are making the worst case better at the cost of making the best case worse. | ||
682 | This way is generally better because we don't have to rebuild the connection/sql query per subfolder, | ||
683 | even if we end up getting more data from the SQL server than we need. | ||
684 | - Francis | ||
685 | */ | ||
686 | try | ||
687 | { | ||
688 | List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); | ||
689 | Dictionary<UUID, List<InventoryFolderBase>> hashtable = new Dictionary<UUID, List<InventoryFolderBase>>(); ; | ||
690 | List<InventoryFolderBase> parentFolder = new List<InventoryFolderBase>(); | ||
691 | bool buildResultsFromHashTable = false; | ||
692 | |||
693 | lock (m_dbLock) | ||
694 | { | ||
695 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
696 | { | ||
697 | dbcon.Open(); | ||
698 | |||
699 | /* Fetch the parent folder from the database to determine the agent ID, and if | ||
700 | * we're querying the root of the inventory folder tree */ | ||
701 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon)) | ||
702 | { | ||
703 | result.Parameters.AddWithValue("?uuid", parentID.ToString()); | ||
704 | |||
705 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
706 | { | ||
707 | // Should be at most 1 result | ||
708 | while (reader.Read()) | ||
709 | parentFolder.Add(readInventoryFolder(reader)); | ||
710 | } | ||
711 | } | ||
712 | |||
713 | if (parentFolder.Count >= 1) // No result means parent folder does not exist | ||
714 | { | ||
715 | if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder | ||
716 | { | ||
717 | /* Get all of the agent's folders from the database, put them in a list and return it */ | ||
718 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon)) | ||
719 | { | ||
720 | result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); | ||
721 | |||
722 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
723 | { | ||
724 | while (reader.Read()) | ||
725 | { | ||
726 | InventoryFolderBase curFolder = readInventoryFolder(reader); | ||
727 | if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list | ||
728 | folders.Add(curFolder); | ||
729 | } | ||
730 | } | ||
731 | } | ||
732 | } // if we are querying the root folder | ||
733 | else // else we are querying a subtree of the inventory folder tree | ||
734 | { | ||
735 | /* Get all of the agent's folders from the database, put them all in a hash table | ||
736 | * indexed by their parent ID */ | ||
737 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon)) | ||
738 | { | ||
739 | result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); | ||
740 | |||
741 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
742 | { | ||
743 | while (reader.Read()) | ||
744 | { | ||
745 | InventoryFolderBase curFolder = readInventoryFolder(reader); | ||
746 | if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling | ||
747 | hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list | ||
748 | else // else current folder has no known (yet) siblings | ||
749 | { | ||
750 | List<InventoryFolderBase> siblingList = new List<InventoryFolderBase>(); | ||
751 | siblingList.Add(curFolder); | ||
752 | // Current folder has no known (yet) siblings | ||
753 | hashtable.Add(curFolder.ParentID, siblingList); | ||
754 | } | ||
755 | } // while more items to read from the database | ||
756 | } | ||
757 | } | ||
758 | |||
759 | // Set flag so we know we need to build the results from the hash table after | ||
760 | // we unlock the database | ||
761 | buildResultsFromHashTable = true; | ||
762 | |||
763 | } // else we are querying a subtree of the inventory folder tree | ||
764 | } // if folder parentID exists | ||
765 | |||
766 | if (buildResultsFromHashTable) | ||
767 | { | ||
768 | /* We have all of the user's folders stored in a hash table indexed by their parent ID | ||
769 | * and we need to return the requested subtree. We will build the requested subtree | ||
770 | * by performing a breadth-first-search on the hash table */ | ||
771 | if (hashtable.ContainsKey(parentID)) | ||
772 | folders.AddRange(hashtable[parentID]); | ||
773 | for (int i = 0; i < folders.Count; i++) // **Note: folders.Count is *not* static | ||
774 | if (hashtable.ContainsKey(folders[i].ID)) | ||
775 | folders.AddRange(hashtable[folders[i].ID]); | ||
776 | } | ||
777 | } | ||
778 | } // lock (database) | ||
779 | |||
780 | return folders; | ||
781 | } | ||
782 | catch (Exception e) | ||
783 | { | ||
784 | m_log.Error(e.Message, e); | ||
785 | return null; | ||
786 | } | ||
787 | } | ||
788 | |||
789 | /// <summary> | ||
790 | /// Delete a folder from database | ||
791 | /// </summary> | ||
792 | /// <param name="folderID">the folder UUID</param> | ||
793 | protected void deleteOneFolder(UUID folderID) | ||
794 | { | ||
795 | try | ||
796 | { | ||
797 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
798 | { | ||
799 | dbcon.Open(); | ||
800 | |||
801 | // System folders can never be deleted. Period. | ||
802 | using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid and type=-1", dbcon)) | ||
803 | { | ||
804 | cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
805 | |||
806 | lock (m_dbLock) | ||
807 | cmd.ExecuteNonQuery(); | ||
808 | } | ||
809 | } | ||
810 | } | ||
811 | catch (MySqlException e) | ||
812 | { | ||
813 | m_log.Error(e.Message, e); | ||
814 | } | ||
815 | } | ||
816 | |||
817 | /// <summary> | ||
818 | /// Delete all item in a folder | ||
819 | /// </summary> | ||
820 | /// <param name="folderID">the folder UUID</param> | ||
821 | protected void deleteItemsInFolder(UUID folderID) | ||
822 | { | ||
823 | try | ||
824 | { | ||
825 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
826 | { | ||
827 | dbcon.Open(); | ||
828 | |||
829 | using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", dbcon)) | ||
830 | { | ||
831 | cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
832 | |||
833 | lock (m_dbLock) | ||
834 | cmd.ExecuteNonQuery(); | ||
835 | } | ||
836 | } | ||
837 | } | ||
838 | catch (MySqlException e) | ||
839 | { | ||
840 | m_log.Error(e.ToString()); | ||
841 | } | ||
842 | } | ||
843 | |||
844 | /// <summary> | ||
845 | /// Deletes an inventory folder | ||
846 | /// </summary> | ||
847 | /// <param name="folderId">Id of folder to delete</param> | ||
848 | public void deleteInventoryFolder(UUID folderID) | ||
849 | { | ||
850 | List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID); | ||
851 | |||
852 | //Delete all sub-folders | ||
853 | foreach (InventoryFolderBase f in subFolders) | ||
854 | { | ||
855 | deleteOneFolder(f.ID); | ||
856 | deleteItemsInFolder(f.ID); | ||
857 | } | ||
858 | |||
859 | //Delete the actual row | ||
860 | deleteOneFolder(folderID); | ||
861 | deleteItemsInFolder(folderID); | ||
862 | } | ||
863 | |||
864 | public List<InventoryItemBase> fetchActiveGestures(UUID avatarID) | ||
865 | { | ||
866 | lock (m_dbLock) | ||
867 | { | ||
868 | try | ||
869 | { | ||
870 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
871 | { | ||
872 | dbcon.Open(); | ||
873 | |||
874 | using (MySqlCommand sqlCmd = new MySqlCommand( | ||
875 | "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags & 1", dbcon)) | ||
876 | { | ||
877 | sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString()); | ||
878 | sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); | ||
879 | |||
880 | using (MySqlDataReader result = sqlCmd.ExecuteReader()) | ||
881 | { | ||
882 | List<InventoryItemBase> list = new List<InventoryItemBase>(); | ||
883 | while (result.Read()) | ||
884 | { | ||
885 | InventoryItemBase item = readInventoryItem(result); | ||
886 | if (item != null) | ||
887 | list.Add(item); | ||
888 | } | ||
889 | return list; | ||
890 | } | ||
891 | } | ||
892 | } | ||
893 | } | ||
894 | catch (Exception e) | ||
895 | { | ||
896 | m_log.Error(e.Message, e); | ||
897 | return null; | ||
898 | } | ||
899 | } | ||
900 | } | ||
901 | } | ||
902 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLMigrations.cs b/OpenSim/Data/MySQL/MySQLMigrations.cs new file mode 100644 index 0000000..81a0e83 --- /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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Data.Common; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | ||
34 | using System.Text.RegularExpressions; | ||
35 | using log4net; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | |||
38 | namespace 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/MySQLOfflineIMData.cs b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs new file mode 100644 index 0000000..bafd204 --- /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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Data.MySQL; | ||
35 | |||
36 | using OpenMetaverse; | ||
37 | using MySql.Data.MySqlClient; | ||
38 | |||
39 | namespace 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..3f90639 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | |||
38 | namespace OpenSim.Data.MySQL | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// A MySQL Interface for the Grid Server | ||
42 | /// </summary> | ||
43 | public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>, | ||
44 | IPresenceData | ||
45 | { | ||
46 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | public MySQLPresenceData(string connectionString, string realm) : | ||
49 | base(connectionString, realm, "Presence") | ||
50 | { | ||
51 | } | ||
52 | |||
53 | public PresenceData Get(UUID sessionID) | ||
54 | { | ||
55 | PresenceData[] ret = Get("SessionID", | ||
56 | sessionID.ToString()); | ||
57 | |||
58 | if (ret.Length == 0) | ||
59 | return null; | ||
60 | |||
61 | return ret[0]; | ||
62 | } | ||
63 | |||
64 | public void LogoutRegionAgents(UUID regionID) | ||
65 | { | ||
66 | using (MySqlCommand cmd = new MySqlCommand()) | ||
67 | { | ||
68 | cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm); | ||
69 | |||
70 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
71 | |||
72 | ExecuteNonQuery(cmd); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | public bool ReportAgent(UUID sessionID, UUID regionID) | ||
77 | { | ||
78 | PresenceData[] pd = Get("SessionID", sessionID.ToString()); | ||
79 | if (pd.Length == 0) | ||
80 | return false; | ||
81 | |||
82 | if (regionID == UUID.Zero) | ||
83 | return false; | ||
84 | |||
85 | using (MySqlCommand cmd = new MySqlCommand()) | ||
86 | { | ||
87 | cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm); | ||
88 | |||
89 | cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); | ||
90 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
91 | |||
92 | if (ExecuteNonQuery(cmd) == 0) | ||
93 | return false; | ||
94 | } | ||
95 | |||
96 | return true; | ||
97 | } | ||
98 | |||
99 | public bool VerifyAgent(UUID agentId, UUID secureSessionID) | ||
100 | { | ||
101 | PresenceData[] ret = Get("SecureSessionID", | ||
102 | secureSessionID.ToString()); | ||
103 | |||
104 | if (ret.Length == 0) | ||
105 | return false; | ||
106 | |||
107 | if(ret[0].UserID != agentId.ToString()) | ||
108 | return false; | ||
109 | |||
110 | return true; | ||
111 | } | ||
112 | } | ||
113 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs new file mode 100644 index 0000000..2ad7590 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using System.Reflection; | ||
33 | using MySql.Data.MySqlClient; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Data; | ||
37 | using RegionFlags = OpenSim.Framework.RegionFlags; | ||
38 | |||
39 | namespace 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 | } | ||
64 | } | ||
65 | |||
66 | public List<RegionData> Get(string regionName, UUID scopeID) | ||
67 | { | ||
68 | string command = "select * from `"+m_Realm+"` where regionName like ?regionName"; | ||
69 | if (scopeID != UUID.Zero) | ||
70 | command += " and ScopeID = ?scopeID"; | ||
71 | |||
72 | command += " order by regionName"; | ||
73 | |||
74 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
75 | { | ||
76 | cmd.Parameters.AddWithValue("?regionName", regionName); | ||
77 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
78 | |||
79 | return RunCommand(cmd); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | public RegionData Get(int posX, int posY, UUID scopeID) | ||
84 | { | ||
85 | string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY"; | ||
86 | if (scopeID != UUID.Zero) | ||
87 | command += " and ScopeID = ?scopeID"; | ||
88 | |||
89 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
90 | { | ||
91 | cmd.Parameters.AddWithValue("?posX", posX.ToString()); | ||
92 | cmd.Parameters.AddWithValue("?posY", posY.ToString()); | ||
93 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
94 | |||
95 | List<RegionData> ret = RunCommand(cmd); | ||
96 | if (ret.Count == 0) | ||
97 | return null; | ||
98 | |||
99 | return ret[0]; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | public RegionData Get(UUID regionID, UUID scopeID) | ||
104 | { | ||
105 | string command = "select * from `"+m_Realm+"` where uuid = ?regionID"; | ||
106 | if (scopeID != UUID.Zero) | ||
107 | command += " and ScopeID = ?scopeID"; | ||
108 | |||
109 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
110 | { | ||
111 | cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); | ||
112 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
113 | |||
114 | List<RegionData> ret = RunCommand(cmd); | ||
115 | if (ret.Count == 0) | ||
116 | return null; | ||
117 | |||
118 | return ret[0]; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID) | ||
123 | { | ||
124 | string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY"; | ||
125 | if (scopeID != UUID.Zero) | ||
126 | command += " and ScopeID = ?scopeID"; | ||
127 | |||
128 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
129 | { | ||
130 | cmd.Parameters.AddWithValue("?startX", startX.ToString()); | ||
131 | cmd.Parameters.AddWithValue("?startY", startY.ToString()); | ||
132 | cmd.Parameters.AddWithValue("?endX", endX.ToString()); | ||
133 | cmd.Parameters.AddWithValue("?endY", endY.ToString()); | ||
134 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
135 | |||
136 | return RunCommand(cmd); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | public List<RegionData> RunCommand(MySqlCommand cmd) | ||
141 | { | ||
142 | List<RegionData> retList = new List<RegionData>(); | ||
143 | |||
144 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
145 | { | ||
146 | dbcon.Open(); | ||
147 | cmd.Connection = dbcon; | ||
148 | |||
149 | using (IDataReader result = cmd.ExecuteReader()) | ||
150 | { | ||
151 | while (result.Read()) | ||
152 | { | ||
153 | RegionData ret = new RegionData(); | ||
154 | ret.Data = new Dictionary<string, object>(); | ||
155 | |||
156 | ret.RegionID = DBGuid.FromDB(result["uuid"]); | ||
157 | ret.ScopeID = DBGuid.FromDB(result["ScopeID"]); | ||
158 | |||
159 | ret.RegionName = result["regionName"].ToString(); | ||
160 | ret.posX = Convert.ToInt32(result["locX"]); | ||
161 | ret.posY = Convert.ToInt32(result["locY"]); | ||
162 | ret.sizeX = Convert.ToInt32(result["sizeX"]); | ||
163 | ret.sizeY = Convert.ToInt32(result["sizeY"]); | ||
164 | |||
165 | CheckColumnNames(result); | ||
166 | |||
167 | foreach (string s in m_ColumnNames) | ||
168 | { | ||
169 | if (s == "uuid") | ||
170 | continue; | ||
171 | if (s == "ScopeID") | ||
172 | continue; | ||
173 | if (s == "regionName") | ||
174 | continue; | ||
175 | if (s == "locX") | ||
176 | continue; | ||
177 | if (s == "locY") | ||
178 | continue; | ||
179 | |||
180 | object value = result[s]; | ||
181 | if (value is DBNull) | ||
182 | ret.Data[s] = null; | ||
183 | else | ||
184 | ret.Data[s] = result[s].ToString(); | ||
185 | } | ||
186 | |||
187 | retList.Add(ret); | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return retList; | ||
193 | } | ||
194 | |||
195 | private void CheckColumnNames(IDataReader result) | ||
196 | { | ||
197 | if (m_ColumnNames != null) | ||
198 | return; | ||
199 | |||
200 | List<string> columnNames = new List<string>(); | ||
201 | |||
202 | DataTable schemaTable = result.GetSchemaTable(); | ||
203 | foreach (DataRow row in schemaTable.Rows) | ||
204 | { | ||
205 | if (row["ColumnName"] != null) | ||
206 | columnNames.Add(row["ColumnName"].ToString()); | ||
207 | } | ||
208 | |||
209 | m_ColumnNames = columnNames; | ||
210 | } | ||
211 | |||
212 | public bool Store(RegionData data) | ||
213 | { | ||
214 | if (data.Data.ContainsKey("uuid")) | ||
215 | data.Data.Remove("uuid"); | ||
216 | if (data.Data.ContainsKey("ScopeID")) | ||
217 | data.Data.Remove("ScopeID"); | ||
218 | if (data.Data.ContainsKey("regionName")) | ||
219 | data.Data.Remove("regionName"); | ||
220 | if (data.Data.ContainsKey("posX")) | ||
221 | data.Data.Remove("posX"); | ||
222 | if (data.Data.ContainsKey("posY")) | ||
223 | data.Data.Remove("posY"); | ||
224 | if (data.Data.ContainsKey("sizeX")) | ||
225 | data.Data.Remove("sizeX"); | ||
226 | if (data.Data.ContainsKey("sizeY")) | ||
227 | data.Data.Remove("sizeY"); | ||
228 | if (data.Data.ContainsKey("locX")) | ||
229 | data.Data.Remove("locX"); | ||
230 | if (data.Data.ContainsKey("locY")) | ||
231 | data.Data.Remove("locY"); | ||
232 | |||
233 | if (data.RegionName.Length > 128) | ||
234 | data.RegionName = data.RegionName.Substring(0, 128); | ||
235 | |||
236 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
237 | |||
238 | using (MySqlCommand cmd = new MySqlCommand()) | ||
239 | { | ||
240 | string update = "update `" + m_Realm + "` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY"; | ||
241 | foreach (string field in fields) | ||
242 | { | ||
243 | update += ", "; | ||
244 | update += "`" + field + "` = ?" + field; | ||
245 | |||
246 | cmd.Parameters.AddWithValue("?" + field, data.Data[field]); | ||
247 | } | ||
248 | |||
249 | update += " where uuid = ?regionID"; | ||
250 | |||
251 | if (data.ScopeID != UUID.Zero) | ||
252 | update += " and ScopeID = ?scopeID"; | ||
253 | |||
254 | cmd.CommandText = update; | ||
255 | cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); | ||
256 | cmd.Parameters.AddWithValue("?regionName", data.RegionName); | ||
257 | cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); | ||
258 | cmd.Parameters.AddWithValue("?posX", data.posX.ToString()); | ||
259 | cmd.Parameters.AddWithValue("?posY", data.posY.ToString()); | ||
260 | cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString()); | ||
261 | cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString()); | ||
262 | |||
263 | if (ExecuteNonQuery(cmd) < 1) | ||
264 | { | ||
265 | string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" + | ||
266 | String.Join("`, `", fields) + | ||
267 | "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")"; | ||
268 | |||
269 | cmd.CommandText = insert; | ||
270 | |||
271 | if (ExecuteNonQuery(cmd) < 1) | ||
272 | { | ||
273 | return false; | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | |||
278 | return true; | ||
279 | } | ||
280 | |||
281 | public bool SetDataItem(UUID regionID, string item, string value) | ||
282 | { | ||
283 | using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where uuid = ?UUID")) | ||
284 | { | ||
285 | cmd.Parameters.AddWithValue("?" + item, value); | ||
286 | cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); | ||
287 | |||
288 | if (ExecuteNonQuery(cmd) > 0) | ||
289 | return true; | ||
290 | } | ||
291 | |||
292 | return false; | ||
293 | } | ||
294 | |||
295 | public bool Delete(UUID regionID) | ||
296 | { | ||
297 | using (MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + "` where uuid = ?UUID")) | ||
298 | { | ||
299 | cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); | ||
300 | |||
301 | if (ExecuteNonQuery(cmd) > 0) | ||
302 | return true; | ||
303 | } | ||
304 | |||
305 | return false; | ||
306 | } | ||
307 | |||
308 | public List<RegionData> GetDefaultRegions(UUID scopeID) | ||
309 | { | ||
310 | return Get((int)RegionFlags.DefaultRegion, scopeID); | ||
311 | } | ||
312 | |||
313 | public List<RegionData> GetDefaultHypergridRegions(UUID scopeID) | ||
314 | { | ||
315 | return Get((int)RegionFlags.DefaultHGRegion, scopeID); | ||
316 | } | ||
317 | |||
318 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) | ||
319 | { | ||
320 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); | ||
321 | RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y); | ||
322 | regions.Sort(distanceComparer); | ||
323 | return regions; | ||
324 | } | ||
325 | |||
326 | public List<RegionData> GetHyperlinks(UUID scopeID) | ||
327 | { | ||
328 | return Get((int)RegionFlags.Hyperlink, scopeID); | ||
329 | } | ||
330 | |||
331 | private List<RegionData> Get(int regionFlags, UUID scopeID) | ||
332 | { | ||
333 | string command = "select * from `" + m_Realm + "` where (flags & " + regionFlags.ToString() + ") <> 0"; | ||
334 | if (scopeID != UUID.Zero) | ||
335 | command += " and ScopeID = ?scopeID"; | ||
336 | |||
337 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
338 | { | ||
339 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
340 | |||
341 | return RunCommand(cmd); | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | } \ 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..bb0ab75 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs | |||
@@ -0,0 +1,2093 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Drawing; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | ||
34 | using System.Threading; | ||
35 | using log4net; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | using OpenSim.Data; | ||
42 | |||
43 | namespace 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 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 | } | ||
92 | } | ||
93 | |||
94 | private IDataReader ExecuteReader(MySqlCommand c) | ||
95 | { | ||
96 | IDataReader r = null; | ||
97 | |||
98 | try | ||
99 | { | ||
100 | r = c.ExecuteReader(); | ||
101 | } | ||
102 | catch (Exception e) | ||
103 | { | ||
104 | m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e); | ||
105 | throw; | ||
106 | } | ||
107 | |||
108 | return r; | ||
109 | } | ||
110 | |||
111 | private void ExecuteNonQuery(MySqlCommand c) | ||
112 | { | ||
113 | try | ||
114 | { | ||
115 | c.ExecuteNonQuery(); | ||
116 | } | ||
117 | catch (Exception e) | ||
118 | { | ||
119 | m_log.Error("[REGION DB]: MySQL error in ExecuteNonQuery: " + e.Message); | ||
120 | throw; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | public void Dispose() {} | ||
125 | |||
126 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) | ||
127 | { | ||
128 | uint flags = obj.RootPart.GetEffectiveObjectFlags(); | ||
129 | |||
130 | // Eligibility check | ||
131 | // | ||
132 | // PrimFlags.Temporary is not used in OpenSim code and cannot | ||
133 | // be guaranteed to always be clear. Don't check it. | ||
134 | // if ((flags & (uint)PrimFlags.Temporary) != 0) | ||
135 | // return; | ||
136 | if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) | ||
137 | return; | ||
138 | |||
139 | lock (m_dbLock) | ||
140 | { | ||
141 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
142 | { | ||
143 | dbcon.Open(); | ||
144 | |||
145 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
146 | { | ||
147 | foreach (SceneObjectPart prim in obj.Parts) | ||
148 | { | ||
149 | cmd.Parameters.Clear(); | ||
150 | |||
151 | cmd.CommandText = "replace into prims (" + | ||
152 | "UUID, CreationDate, " + | ||
153 | "Name, Text, Description, " + | ||
154 | "SitName, TouchName, ObjectFlags, " + | ||
155 | "OwnerMask, NextOwnerMask, GroupMask, " + | ||
156 | "EveryoneMask, BaseMask, PositionX, " + | ||
157 | "PositionY, PositionZ, GroupPositionX, " + | ||
158 | "GroupPositionY, GroupPositionZ, VelocityX, " + | ||
159 | "VelocityY, VelocityZ, AngularVelocityX, " + | ||
160 | "AngularVelocityY, AngularVelocityZ, " + | ||
161 | "AccelerationX, AccelerationY, " + | ||
162 | "AccelerationZ, RotationX, " + | ||
163 | "RotationY, RotationZ, " + | ||
164 | "RotationW, SitTargetOffsetX, " + | ||
165 | "SitTargetOffsetY, SitTargetOffsetZ, " + | ||
166 | "SitTargetOrientW, SitTargetOrientX, " + | ||
167 | "SitTargetOrientY, SitTargetOrientZ, " + | ||
168 | "RegionUUID, CreatorID, " + | ||
169 | "OwnerID, GroupID, " + | ||
170 | "LastOwnerID, SceneGroupID, " + | ||
171 | "PayPrice, PayButton1, " + | ||
172 | "PayButton2, PayButton3, " + | ||
173 | "PayButton4, LoopedSound, " + | ||
174 | "LoopedSoundGain, TextureAnimation, " + | ||
175 | "OmegaX, OmegaY, OmegaZ, " + | ||
176 | "CameraEyeOffsetX, CameraEyeOffsetY, " + | ||
177 | "CameraEyeOffsetZ, CameraAtOffsetX, " + | ||
178 | "CameraAtOffsetY, CameraAtOffsetZ, " + | ||
179 | "ForceMouselook, ScriptAccessPin, " + | ||
180 | "AllowedDrop, DieAtEdge, " + | ||
181 | "SalePrice, SaleType, " + | ||
182 | "ColorR, ColorG, ColorB, ColorA, " + | ||
183 | "ParticleSystem, ClickAction, Material, " + | ||
184 | "CollisionSound, CollisionSoundVolume, " + | ||
185 | "PassTouches, " + | ||
186 | "LinkNumber, MediaURL, AttachedPosX, " + | ||
187 | "AttachedPosY, AttachedPosZ, KeyframeMotion, " + | ||
188 | "PhysicsShapeType, Density, GravityModifier, " + | ||
189 | "Friction, Restitution, DynAttrs " + | ||
190 | ") values (" + "?UUID, " + | ||
191 | "?CreationDate, ?Name, ?Text, " + | ||
192 | "?Description, ?SitName, ?TouchName, " + | ||
193 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + | ||
194 | "?GroupMask, ?EveryoneMask, ?BaseMask, " + | ||
195 | "?PositionX, ?PositionY, ?PositionZ, " + | ||
196 | "?GroupPositionX, ?GroupPositionY, " + | ||
197 | "?GroupPositionZ, ?VelocityX, " + | ||
198 | "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + | ||
199 | "?AngularVelocityY, ?AngularVelocityZ, " + | ||
200 | "?AccelerationX, ?AccelerationY, " + | ||
201 | "?AccelerationZ, ?RotationX, " + | ||
202 | "?RotationY, ?RotationZ, " + | ||
203 | "?RotationW, ?SitTargetOffsetX, " + | ||
204 | "?SitTargetOffsetY, ?SitTargetOffsetZ, " + | ||
205 | "?SitTargetOrientW, ?SitTargetOrientX, " + | ||
206 | "?SitTargetOrientY, ?SitTargetOrientZ, " + | ||
207 | "?RegionUUID, ?CreatorID, ?OwnerID, " + | ||
208 | "?GroupID, ?LastOwnerID, ?SceneGroupID, " + | ||
209 | "?PayPrice, ?PayButton1, ?PayButton2, " + | ||
210 | "?PayButton3, ?PayButton4, ?LoopedSound, " + | ||
211 | "?LoopedSoundGain, ?TextureAnimation, " + | ||
212 | "?OmegaX, ?OmegaY, ?OmegaZ, " + | ||
213 | "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + | ||
214 | "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + | ||
215 | "?CameraAtOffsetY, ?CameraAtOffsetZ, " + | ||
216 | "?ForceMouselook, ?ScriptAccessPin, " + | ||
217 | "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + | ||
218 | "?SaleType, ?ColorR, ?ColorG, " + | ||
219 | "?ColorB, ?ColorA, ?ParticleSystem, " + | ||
220 | "?ClickAction, ?Material, ?CollisionSound, " + | ||
221 | "?CollisionSoundVolume, ?PassTouches, " + | ||
222 | "?LinkNumber, ?MediaURL, ?AttachedPosX, " + | ||
223 | "?AttachedPosY, ?AttachedPosZ, ?KeyframeMotion, " + | ||
224 | "?PhysicsShapeType, ?Density, ?GravityModifier, " + | ||
225 | "?Friction, ?Restitution, ?DynAttrs)"; | ||
226 | |||
227 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); | ||
228 | |||
229 | ExecuteNonQuery(cmd); | ||
230 | |||
231 | cmd.Parameters.Clear(); | ||
232 | |||
233 | cmd.CommandText = "replace into primshapes (" + | ||
234 | "UUID, Shape, ScaleX, ScaleY, " + | ||
235 | "ScaleZ, PCode, PathBegin, PathEnd, " + | ||
236 | "PathScaleX, PathScaleY, PathShearX, " + | ||
237 | "PathShearY, PathSkew, PathCurve, " + | ||
238 | "PathRadiusOffset, PathRevolutions, " + | ||
239 | "PathTaperX, PathTaperY, PathTwist, " + | ||
240 | "PathTwistBegin, ProfileBegin, ProfileEnd, " + | ||
241 | "ProfileCurve, ProfileHollow, Texture, " + | ||
242 | "ExtraParams, State, LastAttachPoint, Media) " + | ||
243 | "values (?UUID, " + | ||
244 | "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + | ||
245 | "?PCode, ?PathBegin, ?PathEnd, " + | ||
246 | "?PathScaleX, ?PathScaleY, " + | ||
247 | "?PathShearX, ?PathShearY, " + | ||
248 | "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + | ||
249 | "?PathRevolutions, ?PathTaperX, " + | ||
250 | "?PathTaperY, ?PathTwist, " + | ||
251 | "?PathTwistBegin, ?ProfileBegin, " + | ||
252 | "?ProfileEnd, ?ProfileCurve, " + | ||
253 | "?ProfileHollow, ?Texture, ?ExtraParams, " + | ||
254 | "?State, ?LastAttachPoint, ?Media)"; | ||
255 | |||
256 | FillShapeCommand(cmd, prim); | ||
257 | |||
258 | ExecuteNonQuery(cmd); | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | |||
265 | public void RemoveObject(UUID obj, UUID regionUUID) | ||
266 | { | ||
267 | // m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID); | ||
268 | |||
269 | List<UUID> uuids = new List<UUID>(); | ||
270 | |||
271 | // Formerly, this used to check the region UUID. | ||
272 | // That makes no sense, as we remove the contents of a prim | ||
273 | // unconditionally, but the prim dependent on the region ID. | ||
274 | // So, we would destroy an object and cause hard to detect | ||
275 | // issues if we delete the contents only. Deleting it all may | ||
276 | // cause the loss of a prim, but is cleaner. | ||
277 | // It's also faster because it uses the primary key. | ||
278 | // | ||
279 | lock (m_dbLock) | ||
280 | { | ||
281 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
282 | { | ||
283 | dbcon.Open(); | ||
284 | |||
285 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
286 | { | ||
287 | cmd.CommandText = "select UUID from prims where SceneGroupID= ?UUID"; | ||
288 | cmd.Parameters.AddWithValue("UUID", obj.ToString()); | ||
289 | |||
290 | using (IDataReader reader = ExecuteReader(cmd)) | ||
291 | { | ||
292 | while (reader.Read()) | ||
293 | uuids.Add(DBGuid.FromDB(reader["UUID"].ToString())); | ||
294 | } | ||
295 | |||
296 | // delete the main prims | ||
297 | cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; | ||
298 | ExecuteNonQuery(cmd); | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | |||
303 | // there is no way this should be < 1 unless there is | ||
304 | // a very corrupt database, but in that case be extra | ||
305 | // safe anyway. | ||
306 | if (uuids.Count > 0) | ||
307 | { | ||
308 | RemoveShapes(uuids); | ||
309 | RemoveItems(uuids); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | /// <summary> | ||
314 | /// Remove all persisted items of the given prim. | ||
315 | /// The caller must acquire the necessrary synchronization locks | ||
316 | /// </summary> | ||
317 | /// <param name="uuid">the Item UUID</param> | ||
318 | private void RemoveItems(UUID uuid) | ||
319 | { | ||
320 | lock (m_dbLock) | ||
321 | { | ||
322 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
323 | { | ||
324 | dbcon.Open(); | ||
325 | |||
326 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
327 | { | ||
328 | cmd.CommandText = "delete from primitems where PrimID = ?PrimID"; | ||
329 | cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); | ||
330 | |||
331 | ExecuteNonQuery(cmd); | ||
332 | } | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /// <summary> | ||
338 | /// Remove all persisted shapes for a list of prims | ||
339 | /// The caller must acquire the necessrary synchronization locks | ||
340 | /// </summary> | ||
341 | /// <param name="uuids">the list of UUIDs</param> | ||
342 | private void RemoveShapes(List<UUID> uuids) | ||
343 | { | ||
344 | lock (m_dbLock) | ||
345 | { | ||
346 | string sql = "delete from primshapes where "; | ||
347 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
348 | { | ||
349 | dbcon.Open(); | ||
350 | |||
351 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
352 | { | ||
353 | for (int i = 0; i < uuids.Count; i++) | ||
354 | { | ||
355 | if ((i + 1) == uuids.Count) | ||
356 | {// end of the list | ||
357 | sql += "(UUID = ?UUID" + i + ")"; | ||
358 | } | ||
359 | else | ||
360 | { | ||
361 | sql += "(UUID = ?UUID" + i + ") or "; | ||
362 | } | ||
363 | } | ||
364 | cmd.CommandText = sql; | ||
365 | |||
366 | for (int i = 0; i < uuids.Count; i++) | ||
367 | cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); | ||
368 | |||
369 | ExecuteNonQuery(cmd); | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | } | ||
374 | |||
375 | /// <summary> | ||
376 | /// Remove all persisted items for a list of prims | ||
377 | /// The caller must acquire the necessrary synchronization locks | ||
378 | /// </summary> | ||
379 | /// <param name="uuids">the list of UUIDs</param> | ||
380 | private void RemoveItems(List<UUID> uuids) | ||
381 | { | ||
382 | lock (m_dbLock) | ||
383 | { | ||
384 | string sql = "delete from primitems where "; | ||
385 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
386 | { | ||
387 | dbcon.Open(); | ||
388 | |||
389 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
390 | { | ||
391 | for (int i = 0; i < uuids.Count; i++) | ||
392 | { | ||
393 | if ((i + 1) == uuids.Count) | ||
394 | { | ||
395 | // end of the list | ||
396 | sql += "(PrimID = ?PrimID" + i + ")"; | ||
397 | } | ||
398 | else | ||
399 | { | ||
400 | sql += "(PrimID = ?PrimID" + i + ") or "; | ||
401 | } | ||
402 | } | ||
403 | cmd.CommandText = sql; | ||
404 | |||
405 | for (int i = 0; i < uuids.Count; i++) | ||
406 | cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); | ||
407 | |||
408 | ExecuteNonQuery(cmd); | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | |||
414 | public List<SceneObjectGroup> LoadObjects(UUID regionID) | ||
415 | { | ||
416 | const int ROWS_PER_QUERY = 5000; | ||
417 | |||
418 | Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(ROWS_PER_QUERY); | ||
419 | Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>(); | ||
420 | int count = 0; | ||
421 | |||
422 | #region Prim Loading | ||
423 | |||
424 | lock (m_dbLock) | ||
425 | { | ||
426 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
427 | { | ||
428 | dbcon.Open(); | ||
429 | |||
430 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
431 | { | ||
432 | cmd.CommandText = | ||
433 | "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID"; | ||
434 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
435 | cmd.CommandTimeout = 3600; | ||
436 | |||
437 | using (IDataReader reader = ExecuteReader(cmd)) | ||
438 | { | ||
439 | while (reader.Read()) | ||
440 | { | ||
441 | SceneObjectPart prim = BuildPrim(reader); | ||
442 | if (reader["Shape"] is DBNull) | ||
443 | prim.Shape = PrimitiveBaseShape.Default; | ||
444 | else | ||
445 | prim.Shape = BuildShape(reader); | ||
446 | |||
447 | UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString()); | ||
448 | if (parentID != prim.UUID) | ||
449 | prim.ParentUUID = parentID; | ||
450 | |||
451 | prims[prim.UUID] = prim; | ||
452 | |||
453 | ++count; | ||
454 | if (count % ROWS_PER_QUERY == 0) | ||
455 | m_log.Debug("[REGION DB]: Loaded " + count + " prims..."); | ||
456 | } | ||
457 | } | ||
458 | } | ||
459 | } | ||
460 | } | ||
461 | |||
462 | #endregion Prim Loading | ||
463 | |||
464 | #region SceneObjectGroup Creation | ||
465 | |||
466 | // Create all of the SOGs from the root prims first | ||
467 | foreach (SceneObjectPart prim in prims.Values) | ||
468 | { | ||
469 | if (prim.ParentUUID == UUID.Zero) | ||
470 | { | ||
471 | objects[prim.UUID] = new SceneObjectGroup(prim); | ||
472 | } | ||
473 | } | ||
474 | |||
475 | // Add all of the children objects to the SOGs | ||
476 | foreach (SceneObjectPart prim in prims.Values) | ||
477 | { | ||
478 | SceneObjectGroup sog; | ||
479 | if (prim.UUID != prim.ParentUUID) | ||
480 | { | ||
481 | if (objects.TryGetValue(prim.ParentUUID, out sog)) | ||
482 | { | ||
483 | int originalLinkNum = prim.LinkNum; | ||
484 | |||
485 | sog.AddPart(prim); | ||
486 | |||
487 | // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. | ||
488 | // We override that here | ||
489 | if (originalLinkNum != 0) | ||
490 | prim.LinkNum = originalLinkNum; | ||
491 | } | ||
492 | else | ||
493 | { | ||
494 | m_log.WarnFormat( | ||
495 | "[REGION DB]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.", | ||
496 | prim.Name, prim.UUID, regionID, prim.ParentUUID); | ||
497 | } | ||
498 | } | ||
499 | } | ||
500 | |||
501 | #endregion SceneObjectGroup Creation | ||
502 | |||
503 | m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); | ||
504 | |||
505 | #region Prim Inventory Loading | ||
506 | |||
507 | // Instead of attempting to LoadItems on every prim, | ||
508 | // most of which probably have no items... get a | ||
509 | // list from DB of all prims which have items and | ||
510 | // LoadItems only on those | ||
511 | List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>(); | ||
512 | lock (m_dbLock) | ||
513 | { | ||
514 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
515 | { | ||
516 | dbcon.Open(); | ||
517 | |||
518 | using (MySqlCommand itemCmd = dbcon.CreateCommand()) | ||
519 | { | ||
520 | itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems"; | ||
521 | using (IDataReader itemReader = ExecuteReader(itemCmd)) | ||
522 | { | ||
523 | while (itemReader.Read()) | ||
524 | { | ||
525 | if (!(itemReader["primID"] is DBNull)) | ||
526 | { | ||
527 | UUID primID = DBGuid.FromDB(itemReader["primID"].ToString()); | ||
528 | if (prims.ContainsKey(primID)) | ||
529 | primsWithInventory.Add(prims[primID]); | ||
530 | } | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | |||
537 | foreach (SceneObjectPart prim in primsWithInventory) | ||
538 | { | ||
539 | LoadItems(prim); | ||
540 | } | ||
541 | |||
542 | #endregion Prim Inventory Loading | ||
543 | |||
544 | m_log.DebugFormat("[REGION DB]: Loaded inventory from {0} objects", primsWithInventory.Count); | ||
545 | |||
546 | return new List<SceneObjectGroup>(objects.Values); | ||
547 | } | ||
548 | |||
549 | /// <summary> | ||
550 | /// Load in a prim's persisted inventory. | ||
551 | /// </summary> | ||
552 | /// <param name="prim">The prim</param> | ||
553 | private void LoadItems(SceneObjectPart prim) | ||
554 | { | ||
555 | lock (m_dbLock) | ||
556 | { | ||
557 | List<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); | ||
558 | |||
559 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
560 | { | ||
561 | dbcon.Open(); | ||
562 | |||
563 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
564 | { | ||
565 | cmd.CommandText = "select * from primitems where PrimID = ?PrimID"; | ||
566 | cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); | ||
567 | |||
568 | using (IDataReader reader = ExecuteReader(cmd)) | ||
569 | { | ||
570 | while (reader.Read()) | ||
571 | { | ||
572 | TaskInventoryItem item = BuildItem(reader); | ||
573 | |||
574 | item.ParentID = prim.UUID; // Values in database are often wrong | ||
575 | inventory.Add(item); | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | } | ||
580 | |||
581 | prim.Inventory.RestoreInventoryItems(inventory); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | // Legacy entry point for when terrain was always a 256x256 hieghtmap | ||
586 | public void StoreTerrain(double[,] ter, UUID regionID) | ||
587 | { | ||
588 | StoreTerrain(new HeightmapTerrainData(ter), regionID); | ||
589 | } | ||
590 | |||
591 | public void StoreTerrain(TerrainData terrData, UUID regionID) | ||
592 | { | ||
593 | lock (m_dbLock) | ||
594 | { | ||
595 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
596 | { | ||
597 | dbcon.Open(); | ||
598 | |||
599 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
600 | { | ||
601 | cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; | ||
602 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
603 | |||
604 | ExecuteNonQuery(cmd); | ||
605 | |||
606 | int terrainDBRevision; | ||
607 | Array terrainDBblob; | ||
608 | terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); | ||
609 | |||
610 | m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}", | ||
611 | LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision); | ||
612 | |||
613 | cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)" | ||
614 | + "values (?RegionUUID, ?Revision, ?Heightfield)"; | ||
615 | |||
616 | cmd.Parameters.AddWithValue("Revision", terrainDBRevision); | ||
617 | cmd.Parameters.AddWithValue("Heightfield", terrainDBblob); | ||
618 | |||
619 | ExecuteNonQuery(cmd); | ||
620 | } | ||
621 | } | ||
622 | } | ||
623 | } | ||
624 | |||
625 | // Legacy region loading | ||
626 | public double[,] LoadTerrain(UUID regionID) | ||
627 | { | ||
628 | double[,] ret = null; | ||
629 | TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); | ||
630 | if (terrData != null) | ||
631 | ret = terrData.GetDoubles(); | ||
632 | return ret; | ||
633 | } | ||
634 | |||
635 | // Returns 'null' if region not found | ||
636 | public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) | ||
637 | { | ||
638 | TerrainData terrData = null; | ||
639 | |||
640 | lock (m_dbLock) | ||
641 | { | ||
642 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
643 | { | ||
644 | dbcon.Open(); | ||
645 | |||
646 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
647 | { | ||
648 | cmd.CommandText = "select RegionUUID, Revision, Heightfield " + | ||
649 | "from terrain where RegionUUID = ?RegionUUID " + | ||
650 | "order by Revision desc limit 1"; | ||
651 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
652 | |||
653 | using (IDataReader reader = ExecuteReader(cmd)) | ||
654 | { | ||
655 | while (reader.Read()) | ||
656 | { | ||
657 | int rev = Convert.ToInt32(reader["Revision"]); | ||
658 | byte[] blob = (byte[])reader["Heightfield"]; | ||
659 | terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); | ||
660 | } | ||
661 | } | ||
662 | } | ||
663 | } | ||
664 | } | ||
665 | |||
666 | return terrData; | ||
667 | } | ||
668 | |||
669 | public void RemoveLandObject(UUID globalID) | ||
670 | { | ||
671 | lock (m_dbLock) | ||
672 | { | ||
673 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
674 | { | ||
675 | dbcon.Open(); | ||
676 | |||
677 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
678 | { | ||
679 | cmd.CommandText = "delete from land where UUID = ?UUID"; | ||
680 | cmd.Parameters.AddWithValue("UUID", globalID.ToString()); | ||
681 | |||
682 | ExecuteNonQuery(cmd); | ||
683 | } | ||
684 | } | ||
685 | } | ||
686 | } | ||
687 | |||
688 | public void StoreLandObject(ILandObject parcel) | ||
689 | { | ||
690 | lock (m_dbLock) | ||
691 | { | ||
692 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
693 | { | ||
694 | dbcon.Open(); | ||
695 | |||
696 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
697 | { | ||
698 | cmd.CommandText = "replace into land (UUID, RegionUUID, " + | ||
699 | "LocalLandID, Bitmap, Name, Description, " + | ||
700 | "OwnerUUID, IsGroupOwned, Area, AuctionID, " + | ||
701 | "Category, ClaimDate, ClaimPrice, GroupUUID, " + | ||
702 | "SalePrice, LandStatus, LandFlags, LandingType, " + | ||
703 | "MediaAutoScale, MediaTextureUUID, MediaURL, " + | ||
704 | "MusicURL, PassHours, PassPrice, SnapshotUUID, " + | ||
705 | "UserLocationX, UserLocationY, UserLocationZ, " + | ||
706 | "UserLookAtX, UserLookAtY, UserLookAtZ, " + | ||
707 | "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " + | ||
708 | "MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" + | ||
709 | "?UUID, ?RegionUUID, " + | ||
710 | "?LocalLandID, ?Bitmap, ?Name, ?Description, " + | ||
711 | "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + | ||
712 | "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " + | ||
713 | "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " + | ||
714 | "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " + | ||
715 | "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + | ||
716 | "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + | ||
717 | "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + | ||
718 | "?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+ | ||
719 | "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)"; | ||
720 | |||
721 | FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); | ||
722 | |||
723 | ExecuteNonQuery(cmd); | ||
724 | |||
725 | cmd.CommandText = "delete from landaccesslist where LandUUID = ?UUID"; | ||
726 | |||
727 | ExecuteNonQuery(cmd); | ||
728 | |||
729 | cmd.Parameters.Clear(); | ||
730 | cmd.CommandText = "insert into landaccesslist (LandUUID, " + | ||
731 | "AccessUUID, Flags, Expires) values (?LandUUID, ?AccessUUID, " + | ||
732 | "?Flags, ?Expires)"; | ||
733 | |||
734 | foreach (LandAccessEntry entry in parcel.LandData.ParcelAccessList) | ||
735 | { | ||
736 | FillLandAccessCommand(cmd, entry, parcel.LandData.GlobalID); | ||
737 | ExecuteNonQuery(cmd); | ||
738 | cmd.Parameters.Clear(); | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | } | ||
743 | } | ||
744 | |||
745 | public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) | ||
746 | { | ||
747 | RegionLightShareData nWP = new RegionLightShareData(); | ||
748 | nWP.OnSave += StoreRegionWindlightSettings; | ||
749 | |||
750 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
751 | { | ||
752 | dbcon.Open(); | ||
753 | |||
754 | string command = "select * from `regionwindlight` where region_id = ?regionID"; | ||
755 | |||
756 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
757 | { | ||
758 | cmd.Connection = dbcon; | ||
759 | |||
760 | cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); | ||
761 | |||
762 | IDataReader result = ExecuteReader(cmd); | ||
763 | if (!result.Read()) | ||
764 | { | ||
765 | //No result, so store our default windlight profile and return it | ||
766 | nWP.regionID = regionUUID; | ||
767 | // StoreRegionWindlightSettings(nWP); | ||
768 | return nWP; | ||
769 | } | ||
770 | else | ||
771 | { | ||
772 | nWP.regionID = DBGuid.FromDB(result["region_id"]); | ||
773 | nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); | ||
774 | nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); | ||
775 | nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); | ||
776 | nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); | ||
777 | nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); | ||
778 | nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); | ||
779 | nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); | ||
780 | nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); | ||
781 | nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); | ||
782 | nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); | ||
783 | nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); | ||
784 | nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); | ||
785 | nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); | ||
786 | nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); | ||
787 | nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); | ||
788 | nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); | ||
789 | nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); | ||
790 | UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); | ||
791 | nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); | ||
792 | nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); | ||
793 | nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); | ||
794 | nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); | ||
795 | nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); | ||
796 | nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); | ||
797 | nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); | ||
798 | nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); | ||
799 | nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); | ||
800 | nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); | ||
801 | nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); | ||
802 | nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); | ||
803 | nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); | ||
804 | nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); | ||
805 | nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); | ||
806 | nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); | ||
807 | nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); | ||
808 | nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); | ||
809 | nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); | ||
810 | nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); | ||
811 | nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); | ||
812 | nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); | ||
813 | nWP.eastAngle = Convert.ToSingle(result["east_angle"]); | ||
814 | nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); | ||
815 | nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); | ||
816 | nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); | ||
817 | nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); | ||
818 | nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); | ||
819 | nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); | ||
820 | nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); | ||
821 | nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); | ||
822 | nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); | ||
823 | nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); | ||
824 | nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); | ||
825 | nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); | ||
826 | nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); | ||
827 | nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); | ||
828 | nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); | ||
829 | nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); | ||
830 | nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); | ||
831 | nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); | ||
832 | nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); | ||
833 | nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); | ||
834 | nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); | ||
835 | nWP.valid = true; | ||
836 | } | ||
837 | } | ||
838 | } | ||
839 | |||
840 | return nWP; | ||
841 | } | ||
842 | |||
843 | public RegionSettings LoadRegionSettings(UUID regionUUID) | ||
844 | { | ||
845 | RegionSettings rs = null; | ||
846 | |||
847 | lock (m_dbLock) | ||
848 | { | ||
849 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
850 | { | ||
851 | dbcon.Open(); | ||
852 | |||
853 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
854 | { | ||
855 | cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID"; | ||
856 | cmd.Parameters.AddWithValue("regionUUID", regionUUID); | ||
857 | |||
858 | using (IDataReader reader = ExecuteReader(cmd)) | ||
859 | { | ||
860 | if (reader.Read()) | ||
861 | { | ||
862 | rs = BuildRegionSettings(reader); | ||
863 | rs.OnSave += StoreRegionSettings; | ||
864 | } | ||
865 | else | ||
866 | { | ||
867 | rs = new RegionSettings(); | ||
868 | rs.RegionUUID = regionUUID; | ||
869 | rs.OnSave += StoreRegionSettings; | ||
870 | |||
871 | StoreRegionSettings(rs); | ||
872 | } | ||
873 | } | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | |||
878 | LoadSpawnPoints(rs); | ||
879 | |||
880 | return rs; | ||
881 | } | ||
882 | |||
883 | public void StoreRegionWindlightSettings(RegionLightShareData wl) | ||
884 | { | ||
885 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
886 | { | ||
887 | dbcon.Open(); | ||
888 | |||
889 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
890 | { | ||
891 | cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; | ||
892 | cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; | ||
893 | cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; | ||
894 | cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; | ||
895 | cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; | ||
896 | cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; | ||
897 | cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; | ||
898 | cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; | ||
899 | cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; | ||
900 | cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; | ||
901 | cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; | ||
902 | cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; | ||
903 | cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; | ||
904 | cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; | ||
905 | cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; | ||
906 | cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; | ||
907 | cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; | ||
908 | cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; | ||
909 | cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; | ||
910 | cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; | ||
911 | cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; | ||
912 | cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; | ||
913 | cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; | ||
914 | cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; | ||
915 | cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; | ||
916 | |||
917 | cmd.Parameters.AddWithValue("region_id", wl.regionID); | ||
918 | cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); | ||
919 | cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); | ||
920 | cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); | ||
921 | cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); | ||
922 | cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); | ||
923 | cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); | ||
924 | cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); | ||
925 | cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); | ||
926 | cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); | ||
927 | cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); | ||
928 | cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); | ||
929 | cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); | ||
930 | cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); | ||
931 | cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); | ||
932 | cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); | ||
933 | cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); | ||
934 | cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); | ||
935 | cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); | ||
936 | cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); | ||
937 | cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); | ||
938 | cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); | ||
939 | cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); | ||
940 | cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); | ||
941 | cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); | ||
942 | cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); | ||
943 | cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); | ||
944 | cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); | ||
945 | cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); | ||
946 | cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); | ||
947 | cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); | ||
948 | cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); | ||
949 | cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); | ||
950 | cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); | ||
951 | cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); | ||
952 | cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); | ||
953 | cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); | ||
954 | cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); | ||
955 | cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); | ||
956 | cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); | ||
957 | cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); | ||
958 | cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); | ||
959 | cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); | ||
960 | cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); | ||
961 | cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); | ||
962 | cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); | ||
963 | cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); | ||
964 | cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); | ||
965 | cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); | ||
966 | cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); | ||
967 | cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); | ||
968 | cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); | ||
969 | cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); | ||
970 | cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); | ||
971 | cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); | ||
972 | cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); | ||
973 | cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); | ||
974 | cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); | ||
975 | cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); | ||
976 | cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); | ||
977 | cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); | ||
978 | cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); | ||
979 | cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); | ||
980 | |||
981 | ExecuteNonQuery(cmd); | ||
982 | } | ||
983 | } | ||
984 | } | ||
985 | |||
986 | public void RemoveRegionWindlightSettings(UUID regionID) | ||
987 | { | ||
988 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
989 | { | ||
990 | dbcon.Open(); | ||
991 | |||
992 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
993 | { | ||
994 | cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; | ||
995 | cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); | ||
996 | ExecuteNonQuery(cmd); | ||
997 | } | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | #region RegionEnvironmentSettings | ||
1002 | public string LoadRegionEnvironmentSettings(UUID regionUUID) | ||
1003 | { | ||
1004 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1005 | { | ||
1006 | dbcon.Open(); | ||
1007 | |||
1008 | string command = "select * from `regionenvironment` where region_id = ?region_id"; | ||
1009 | |||
1010 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
1011 | { | ||
1012 | cmd.Connection = dbcon; | ||
1013 | |||
1014 | cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); | ||
1015 | |||
1016 | IDataReader result = ExecuteReader(cmd); | ||
1017 | if (!result.Read()) | ||
1018 | { | ||
1019 | return String.Empty; | ||
1020 | } | ||
1021 | else | ||
1022 | { | ||
1023 | return Convert.ToString(result["llsd_settings"]); | ||
1024 | } | ||
1025 | } | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1029 | public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) | ||
1030 | { | ||
1031 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1032 | { | ||
1033 | dbcon.Open(); | ||
1034 | |||
1035 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1036 | { | ||
1037 | cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; | ||
1038 | |||
1039 | cmd.Parameters.AddWithValue("region_id", regionUUID); | ||
1040 | cmd.Parameters.AddWithValue("llsd_settings", settings); | ||
1041 | |||
1042 | ExecuteNonQuery(cmd); | ||
1043 | } | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1047 | public void RemoveRegionEnvironmentSettings(UUID regionUUID) | ||
1048 | { | ||
1049 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1050 | { | ||
1051 | dbcon.Open(); | ||
1052 | |||
1053 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1054 | { | ||
1055 | cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; | ||
1056 | cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); | ||
1057 | ExecuteNonQuery(cmd); | ||
1058 | } | ||
1059 | } | ||
1060 | } | ||
1061 | #endregion | ||
1062 | |||
1063 | public void StoreRegionSettings(RegionSettings rs) | ||
1064 | { | ||
1065 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1066 | { | ||
1067 | dbcon.Open(); | ||
1068 | |||
1069 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1070 | { | ||
1071 | cmd.CommandText = "replace into regionsettings (regionUUID, " + | ||
1072 | "block_terraform, block_fly, allow_damage, " + | ||
1073 | "restrict_pushing, allow_land_resell, " + | ||
1074 | "allow_land_join_divide, block_show_in_search, " + | ||
1075 | "agent_limit, object_bonus, maturity, " + | ||
1076 | "disable_scripts, disable_collisions, " + | ||
1077 | "disable_physics, terrain_texture_1, " + | ||
1078 | "terrain_texture_2, terrain_texture_3, " + | ||
1079 | "terrain_texture_4, elevation_1_nw, " + | ||
1080 | "elevation_2_nw, elevation_1_ne, " + | ||
1081 | "elevation_2_ne, elevation_1_se, " + | ||
1082 | "elevation_2_se, elevation_1_sw, " + | ||
1083 | "elevation_2_sw, water_height, " + | ||
1084 | "terrain_raise_limit, terrain_lower_limit, " + | ||
1085 | "use_estate_sun, fixed_sun, sun_position, " + | ||
1086 | "covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " + | ||
1087 | "sunvectorz, loaded_creation_datetime, " + | ||
1088 | "loaded_creation_id, map_tile_ID, " + | ||
1089 | "TelehubObject, parcel_tile_ID) " + | ||
1090 | "values (?RegionUUID, ?BlockTerraform, " + | ||
1091 | "?BlockFly, ?AllowDamage, ?RestrictPushing, " + | ||
1092 | "?AllowLandResell, ?AllowLandJoinDivide, " + | ||
1093 | "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + | ||
1094 | "?Maturity, ?DisableScripts, ?DisableCollisions, " + | ||
1095 | "?DisablePhysics, ?TerrainTexture1, " + | ||
1096 | "?TerrainTexture2, ?TerrainTexture3, " + | ||
1097 | "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + | ||
1098 | "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + | ||
1099 | "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + | ||
1100 | "?WaterHeight, ?TerrainRaiseLimit, " + | ||
1101 | "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + | ||
1102 | "?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " + | ||
1103 | "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + | ||
1104 | "?LoadedCreationDateTime, ?LoadedCreationID, " + | ||
1105 | "?TerrainImageID, " + | ||
1106 | "?TelehubObject, ?ParcelImageID)"; | ||
1107 | |||
1108 | FillRegionSettingsCommand(cmd, rs); | ||
1109 | |||
1110 | ExecuteNonQuery(cmd); | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | SaveSpawnPoints(rs); | ||
1115 | } | ||
1116 | |||
1117 | public List<LandData> LoadLandObjects(UUID regionUUID) | ||
1118 | { | ||
1119 | List<LandData> landData = new List<LandData>(); | ||
1120 | |||
1121 | lock (m_dbLock) | ||
1122 | { | ||
1123 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1124 | { | ||
1125 | dbcon.Open(); | ||
1126 | |||
1127 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1128 | { | ||
1129 | cmd.CommandText = "select * from land where RegionUUID = ?RegionUUID"; | ||
1130 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1131 | |||
1132 | using (IDataReader reader = ExecuteReader(cmd)) | ||
1133 | { | ||
1134 | while (reader.Read()) | ||
1135 | { | ||
1136 | LandData newLand = BuildLandData(reader); | ||
1137 | landData.Add(newLand); | ||
1138 | } | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1143 | { | ||
1144 | foreach (LandData land in landData) | ||
1145 | { | ||
1146 | cmd.Parameters.Clear(); | ||
1147 | cmd.CommandText = "select * from landaccesslist where LandUUID = ?LandUUID"; | ||
1148 | cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); | ||
1149 | |||
1150 | using (IDataReader reader = ExecuteReader(cmd)) | ||
1151 | { | ||
1152 | while (reader.Read()) | ||
1153 | { | ||
1154 | land.ParcelAccessList.Add(BuildLandAccessData(reader)); | ||
1155 | } | ||
1156 | } | ||
1157 | } | ||
1158 | } | ||
1159 | } | ||
1160 | } | ||
1161 | |||
1162 | return landData; | ||
1163 | } | ||
1164 | |||
1165 | public void Shutdown() | ||
1166 | { | ||
1167 | } | ||
1168 | |||
1169 | private SceneObjectPart BuildPrim(IDataReader row) | ||
1170 | { | ||
1171 | SceneObjectPart prim = new SceneObjectPart(); | ||
1172 | |||
1173 | // depending on the MySQL connector version, CHAR(36) may be already converted to Guid! | ||
1174 | prim.UUID = DBGuid.FromDB(row["UUID"]); | ||
1175 | prim.CreatorIdentification = (string)row["CreatorID"]; | ||
1176 | prim.OwnerID = DBGuid.FromDB(row["OwnerID"]); | ||
1177 | prim.GroupID = DBGuid.FromDB(row["GroupID"]); | ||
1178 | prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]); | ||
1179 | |||
1180 | // explicit conversion of integers is required, which sort | ||
1181 | // of sucks. No idea if there is a shortcut here or not. | ||
1182 | prim.CreationDate = (int)row["CreationDate"]; | ||
1183 | if (row["Name"] != DBNull.Value) | ||
1184 | prim.Name = (string)row["Name"]; | ||
1185 | else | ||
1186 | prim.Name = String.Empty; | ||
1187 | // Various text fields | ||
1188 | prim.Text = (string)row["Text"]; | ||
1189 | prim.Color = Color.FromArgb((int)row["ColorA"], | ||
1190 | (int)row["ColorR"], | ||
1191 | (int)row["ColorG"], | ||
1192 | (int)row["ColorB"]); | ||
1193 | prim.Description = (string)row["Description"]; | ||
1194 | prim.SitName = (string)row["SitName"]; | ||
1195 | prim.TouchName = (string)row["TouchName"]; | ||
1196 | // Permissions | ||
1197 | prim.Flags = (PrimFlags)(int)row["ObjectFlags"]; | ||
1198 | prim.OwnerMask = (uint)(int)row["OwnerMask"]; | ||
1199 | prim.NextOwnerMask = (uint)(int)row["NextOwnerMask"]; | ||
1200 | prim.GroupMask = (uint)(int)row["GroupMask"]; | ||
1201 | prim.EveryoneMask = (uint)(int)row["EveryoneMask"]; | ||
1202 | prim.BaseMask = (uint)(int)row["BaseMask"]; | ||
1203 | |||
1204 | // Vectors | ||
1205 | prim.OffsetPosition = new Vector3( | ||
1206 | (float)(double)row["PositionX"], | ||
1207 | (float)(double)row["PositionY"], | ||
1208 | (float)(double)row["PositionZ"] | ||
1209 | ); | ||
1210 | prim.GroupPosition = new Vector3( | ||
1211 | (float)(double)row["GroupPositionX"], | ||
1212 | (float)(double)row["GroupPositionY"], | ||
1213 | (float)(double)row["GroupPositionZ"] | ||
1214 | ); | ||
1215 | prim.Velocity = new Vector3( | ||
1216 | (float)(double)row["VelocityX"], | ||
1217 | (float)(double)row["VelocityY"], | ||
1218 | (float)(double)row["VelocityZ"] | ||
1219 | ); | ||
1220 | prim.AngularVelocity = new Vector3( | ||
1221 | (float)(double)row["AngularVelocityX"], | ||
1222 | (float)(double)row["AngularVelocityY"], | ||
1223 | (float)(double)row["AngularVelocityZ"] | ||
1224 | ); | ||
1225 | prim.Acceleration = new Vector3( | ||
1226 | (float)(double)row["AccelerationX"], | ||
1227 | (float)(double)row["AccelerationY"], | ||
1228 | (float)(double)row["AccelerationZ"] | ||
1229 | ); | ||
1230 | // quaternions | ||
1231 | prim.RotationOffset = new Quaternion( | ||
1232 | (float)(double)row["RotationX"], | ||
1233 | (float)(double)row["RotationY"], | ||
1234 | (float)(double)row["RotationZ"], | ||
1235 | (float)(double)row["RotationW"] | ||
1236 | ); | ||
1237 | prim.SitTargetPositionLL = new Vector3( | ||
1238 | (float)(double)row["SitTargetOffsetX"], | ||
1239 | (float)(double)row["SitTargetOffsetY"], | ||
1240 | (float)(double)row["SitTargetOffsetZ"] | ||
1241 | ); | ||
1242 | prim.SitTargetOrientationLL = new Quaternion( | ||
1243 | (float)(double)row["SitTargetOrientX"], | ||
1244 | (float)(double)row["SitTargetOrientY"], | ||
1245 | (float)(double)row["SitTargetOrientZ"], | ||
1246 | (float)(double)row["SitTargetOrientW"] | ||
1247 | ); | ||
1248 | |||
1249 | prim.PayPrice[0] = (int)row["PayPrice"]; | ||
1250 | prim.PayPrice[1] = (int)row["PayButton1"]; | ||
1251 | prim.PayPrice[2] = (int)row["PayButton2"]; | ||
1252 | prim.PayPrice[3] = (int)row["PayButton3"]; | ||
1253 | prim.PayPrice[4] = (int)row["PayButton4"]; | ||
1254 | |||
1255 | prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString()); | ||
1256 | prim.SoundGain = (float)(double)row["LoopedSoundGain"]; | ||
1257 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1258 | |||
1259 | if (!(row["TextureAnimation"] is DBNull)) | ||
1260 | prim.TextureAnimation = (byte[])row["TextureAnimation"]; | ||
1261 | if (!(row["ParticleSystem"] is DBNull)) | ||
1262 | prim.ParticleSystem = (byte[])row["ParticleSystem"]; | ||
1263 | |||
1264 | prim.AngularVelocity = new Vector3( | ||
1265 | (float)(double)row["OmegaX"], | ||
1266 | (float)(double)row["OmegaY"], | ||
1267 | (float)(double)row["OmegaZ"] | ||
1268 | ); | ||
1269 | |||
1270 | prim.SetCameraEyeOffset(new Vector3( | ||
1271 | (float)(double)row["CameraEyeOffsetX"], | ||
1272 | (float)(double)row["CameraEyeOffsetY"], | ||
1273 | (float)(double)row["CameraEyeOffsetZ"] | ||
1274 | )); | ||
1275 | |||
1276 | prim.SetCameraAtOffset(new Vector3( | ||
1277 | (float)(double)row["CameraAtOffsetX"], | ||
1278 | (float)(double)row["CameraAtOffsetY"], | ||
1279 | (float)(double)row["CameraAtOffsetZ"] | ||
1280 | )); | ||
1281 | |||
1282 | prim.SetForceMouselook((sbyte)row["ForceMouselook"] != 0); | ||
1283 | prim.ScriptAccessPin = (int)row["ScriptAccessPin"]; | ||
1284 | prim.AllowedDrop = ((sbyte)row["AllowedDrop"] != 0); | ||
1285 | prim.DIE_AT_EDGE = ((sbyte)row["DieAtEdge"] != 0); | ||
1286 | |||
1287 | prim.SalePrice = (int)row["SalePrice"]; | ||
1288 | prim.ObjectSaleType = unchecked((byte)(sbyte)row["SaleType"]); | ||
1289 | |||
1290 | prim.Material = unchecked((byte)(sbyte)row["Material"]); | ||
1291 | |||
1292 | if (!(row["ClickAction"] is DBNull)) | ||
1293 | prim.ClickAction = unchecked((byte)(sbyte)row["ClickAction"]); | ||
1294 | |||
1295 | prim.CollisionSound = DBGuid.FromDB(row["CollisionSound"]); | ||
1296 | prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"]; | ||
1297 | |||
1298 | prim.PassTouches = ((sbyte)row["PassTouches"] != 0); | ||
1299 | prim.LinkNum = (int)row["LinkNumber"]; | ||
1300 | |||
1301 | if (!(row["MediaURL"] is System.DBNull)) | ||
1302 | prim.MediaUrl = (string)row["MediaURL"]; | ||
1303 | |||
1304 | if (!(row["AttachedPosX"] is System.DBNull)) | ||
1305 | { | ||
1306 | prim.AttachedPos = new Vector3( | ||
1307 | (float)(double)row["AttachedPosX"], | ||
1308 | (float)(double)row["AttachedPosY"], | ||
1309 | (float)(double)row["AttachedPosZ"] | ||
1310 | ); | ||
1311 | } | ||
1312 | |||
1313 | if (!(row["DynAttrs"] is System.DBNull)) | ||
1314 | prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); | ||
1315 | else | ||
1316 | prim.DynAttrs = new DAMap(); | ||
1317 | |||
1318 | if (!(row["KeyframeMotion"] is DBNull)) | ||
1319 | { | ||
1320 | Byte[] data = (byte[])row["KeyframeMotion"]; | ||
1321 | if (data.Length > 0) | ||
1322 | prim.KeyframeMotion = KeyframeMotion.FromData(null, data); | ||
1323 | else | ||
1324 | prim.KeyframeMotion = null; | ||
1325 | } | ||
1326 | else | ||
1327 | { | ||
1328 | prim.KeyframeMotion = null; | ||
1329 | } | ||
1330 | |||
1331 | prim.PhysicsShapeType = (byte)Convert.ToInt32(row["PhysicsShapeType"].ToString()); | ||
1332 | prim.Density = (float)(double)row["Density"]; | ||
1333 | prim.GravityModifier = (float)(double)row["GravityModifier"]; | ||
1334 | prim.Friction = (float)(double)row["Friction"]; | ||
1335 | prim.Restitution = (float)(double)row["Restitution"]; | ||
1336 | |||
1337 | return prim; | ||
1338 | } | ||
1339 | |||
1340 | /// <summary> | ||
1341 | /// Build a prim inventory item from the persisted data. | ||
1342 | /// </summary> | ||
1343 | /// <param name="row"></param> | ||
1344 | /// <returns></returns> | ||
1345 | private static TaskInventoryItem BuildItem(IDataReader row) | ||
1346 | { | ||
1347 | TaskInventoryItem taskItem = new TaskInventoryItem(); | ||
1348 | |||
1349 | taskItem.ItemID = DBGuid.FromDB(row["itemID"]); | ||
1350 | taskItem.ParentPartID = DBGuid.FromDB(row["primID"]); | ||
1351 | taskItem.AssetID = DBGuid.FromDB(row["assetID"]); | ||
1352 | taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]); | ||
1353 | |||
1354 | taskItem.InvType = Convert.ToInt32(row["invType"]); | ||
1355 | taskItem.Type = Convert.ToInt32(row["assetType"]); | ||
1356 | |||
1357 | taskItem.Name = (String)row["name"]; | ||
1358 | taskItem.Description = (String)row["description"]; | ||
1359 | taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); | ||
1360 | taskItem.CreatorIdentification = (String)row["creatorID"]; | ||
1361 | taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]); | ||
1362 | taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]); | ||
1363 | taskItem.GroupID = DBGuid.FromDB(row["groupID"]); | ||
1364 | |||
1365 | taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); | ||
1366 | taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); | ||
1367 | taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); | ||
1368 | taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); | ||
1369 | taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); | ||
1370 | taskItem.Flags = Convert.ToUInt32(row["flags"]); | ||
1371 | |||
1372 | return taskItem; | ||
1373 | } | ||
1374 | |||
1375 | private static RegionSettings BuildRegionSettings(IDataReader row) | ||
1376 | { | ||
1377 | RegionSettings newSettings = new RegionSettings(); | ||
1378 | |||
1379 | newSettings.RegionUUID = DBGuid.FromDB(row["regionUUID"]); | ||
1380 | newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); | ||
1381 | newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); | ||
1382 | newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); | ||
1383 | newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); | ||
1384 | newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); | ||
1385 | newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); | ||
1386 | newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); | ||
1387 | newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); | ||
1388 | newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); | ||
1389 | newSettings.Maturity = Convert.ToInt32(row["maturity"]); | ||
1390 | newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); | ||
1391 | newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); | ||
1392 | newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); | ||
1393 | newSettings.TerrainTexture1 = DBGuid.FromDB(row["terrain_texture_1"]); | ||
1394 | newSettings.TerrainTexture2 = DBGuid.FromDB(row["terrain_texture_2"]); | ||
1395 | newSettings.TerrainTexture3 = DBGuid.FromDB(row["terrain_texture_3"]); | ||
1396 | newSettings.TerrainTexture4 = DBGuid.FromDB(row["terrain_texture_4"]); | ||
1397 | newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); | ||
1398 | newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); | ||
1399 | newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); | ||
1400 | newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); | ||
1401 | newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); | ||
1402 | newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); | ||
1403 | newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); | ||
1404 | newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); | ||
1405 | newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); | ||
1406 | newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); | ||
1407 | newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); | ||
1408 | newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); | ||
1409 | newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]); | ||
1410 | newSettings.SunVector = new Vector3 ( | ||
1411 | Convert.ToSingle(row["sunvectorx"]), | ||
1412 | Convert.ToSingle(row["sunvectory"]), | ||
1413 | Convert.ToSingle(row["sunvectorz"]) | ||
1414 | ); | ||
1415 | newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); | ||
1416 | newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); | ||
1417 | newSettings.Covenant = DBGuid.FromDB(row["covenant"]); | ||
1418 | newSettings.CovenantChangedDateTime = Convert.ToInt32(row["covenant_datetime"]); | ||
1419 | newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); | ||
1420 | |||
1421 | if (row["loaded_creation_id"] is DBNull) | ||
1422 | newSettings.LoadedCreationID = ""; | ||
1423 | else | ||
1424 | newSettings.LoadedCreationID = (String) row["loaded_creation_id"]; | ||
1425 | |||
1426 | newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]); | ||
1427 | newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]); | ||
1428 | newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]); | ||
1429 | |||
1430 | return newSettings; | ||
1431 | } | ||
1432 | |||
1433 | /// <summary> | ||
1434 | /// | ||
1435 | /// </summary> | ||
1436 | /// <param name="row"></param> | ||
1437 | /// <returns></returns> | ||
1438 | private static LandData BuildLandData(IDataReader row) | ||
1439 | { | ||
1440 | LandData newData = new LandData(); | ||
1441 | |||
1442 | newData.GlobalID = DBGuid.FromDB(row["UUID"]); | ||
1443 | newData.LocalID = Convert.ToInt32(row["LocalLandID"]); | ||
1444 | |||
1445 | // Bitmap is a byte[512] | ||
1446 | newData.Bitmap = (Byte[]) row["Bitmap"]; | ||
1447 | |||
1448 | newData.Name = (String) row["Name"]; | ||
1449 | newData.Description = (String) row["Description"]; | ||
1450 | newData.OwnerID = DBGuid.FromDB(row["OwnerUUID"]); | ||
1451 | newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); | ||
1452 | newData.Area = Convert.ToInt32(row["Area"]); | ||
1453 | newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented | ||
1454 | newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]); | ||
1455 | //Enum libsecondlife.Parcel.ParcelCategory | ||
1456 | newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); | ||
1457 | newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); | ||
1458 | newData.GroupID = DBGuid.FromDB(row["GroupUUID"]); | ||
1459 | newData.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
1460 | newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]); | ||
1461 | //Enum. libsecondlife.Parcel.ParcelStatus | ||
1462 | newData.Flags = Convert.ToUInt32(row["LandFlags"]); | ||
1463 | newData.LandingType = Convert.ToByte(row["LandingType"]); | ||
1464 | newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); | ||
1465 | newData.MediaID = DBGuid.FromDB(row["MediaTextureUUID"]); | ||
1466 | newData.MediaURL = (String) row["MediaURL"]; | ||
1467 | newData.MusicURL = (String) row["MusicURL"]; | ||
1468 | newData.PassHours = Convert.ToSingle(row["PassHours"]); | ||
1469 | newData.PassPrice = Convert.ToInt32(row["PassPrice"]); | ||
1470 | UUID authedbuyer = UUID.Zero; | ||
1471 | UUID snapshotID = UUID.Zero; | ||
1472 | |||
1473 | UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer); | ||
1474 | UUID.TryParse((string)row["SnapshotUUID"], out snapshotID); | ||
1475 | newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); | ||
1476 | newData.Dwell = Convert.ToSingle(row["Dwell"]); | ||
1477 | |||
1478 | newData.AuthBuyerID = authedbuyer; | ||
1479 | newData.SnapshotID = snapshotID; | ||
1480 | try | ||
1481 | { | ||
1482 | newData.UserLocation = | ||
1483 | new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), | ||
1484 | Convert.ToSingle(row["UserLocationZ"])); | ||
1485 | newData.UserLookAt = | ||
1486 | new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), | ||
1487 | Convert.ToSingle(row["UserLookAtZ"])); | ||
1488 | } | ||
1489 | catch (InvalidCastException) | ||
1490 | { | ||
1491 | newData.UserLocation = Vector3.Zero; | ||
1492 | newData.UserLookAt = Vector3.Zero; | ||
1493 | m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); | ||
1494 | } | ||
1495 | |||
1496 | newData.MediaDescription = (string) row["MediaDescription"]; | ||
1497 | newData.MediaType = (string) row["MediaType"]; | ||
1498 | newData.MediaWidth = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[0]); | ||
1499 | newData.MediaHeight = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[1]); | ||
1500 | newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); | ||
1501 | newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); | ||
1502 | newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); | ||
1503 | |||
1504 | newData.ParcelAccessList = new List<LandAccessEntry>(); | ||
1505 | |||
1506 | return newData; | ||
1507 | } | ||
1508 | |||
1509 | /// <summary> | ||
1510 | /// | ||
1511 | /// </summary> | ||
1512 | /// <param name="row"></param> | ||
1513 | /// <returns></returns> | ||
1514 | private static LandAccessEntry BuildLandAccessData(IDataReader row) | ||
1515 | { | ||
1516 | LandAccessEntry entry = new LandAccessEntry(); | ||
1517 | entry.AgentID = DBGuid.FromDB(row["AccessUUID"]); | ||
1518 | entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]); | ||
1519 | entry.Expires = Convert.ToInt32(row["Expires"]); | ||
1520 | return entry; | ||
1521 | } | ||
1522 | |||
1523 | /// <summary> | ||
1524 | /// Fill the prim command with prim values | ||
1525 | /// </summary> | ||
1526 | /// <param name="row"></param> | ||
1527 | /// <param name="prim"></param> | ||
1528 | /// <param name="sceneGroupID"></param> | ||
1529 | /// <param name="regionUUID"></param> | ||
1530 | private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) | ||
1531 | { | ||
1532 | cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); | ||
1533 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1534 | cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate); | ||
1535 | cmd.Parameters.AddWithValue("Name", prim.Name); | ||
1536 | cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString()); | ||
1537 | // the UUID of the root part for this SceneObjectGroup | ||
1538 | // various text fields | ||
1539 | cmd.Parameters.AddWithValue("Text", prim.Text); | ||
1540 | cmd.Parameters.AddWithValue("ColorR", prim.Color.R); | ||
1541 | cmd.Parameters.AddWithValue("ColorG", prim.Color.G); | ||
1542 | cmd.Parameters.AddWithValue("ColorB", prim.Color.B); | ||
1543 | cmd.Parameters.AddWithValue("ColorA", prim.Color.A); | ||
1544 | cmd.Parameters.AddWithValue("Description", prim.Description); | ||
1545 | cmd.Parameters.AddWithValue("SitName", prim.SitName); | ||
1546 | cmd.Parameters.AddWithValue("TouchName", prim.TouchName); | ||
1547 | // permissions | ||
1548 | cmd.Parameters.AddWithValue("ObjectFlags", (uint)prim.Flags); | ||
1549 | cmd.Parameters.AddWithValue("CreatorID", prim.CreatorIdentification.ToString()); | ||
1550 | cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); | ||
1551 | cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); | ||
1552 | cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); | ||
1553 | cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); | ||
1554 | cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); | ||
1555 | cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); | ||
1556 | cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask); | ||
1557 | cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask); | ||
1558 | // vectors | ||
1559 | cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X); | ||
1560 | cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y); | ||
1561 | cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z); | ||
1562 | cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X); | ||
1563 | cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y); | ||
1564 | cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z); | ||
1565 | cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X); | ||
1566 | cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y); | ||
1567 | cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z); | ||
1568 | cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X); | ||
1569 | cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y); | ||
1570 | cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z); | ||
1571 | cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X); | ||
1572 | cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y); | ||
1573 | cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z); | ||
1574 | // quaternions | ||
1575 | cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X); | ||
1576 | cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y); | ||
1577 | cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z); | ||
1578 | cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W); | ||
1579 | |||
1580 | // Sit target | ||
1581 | Vector3 sitTargetPos = prim.SitTargetPositionLL; | ||
1582 | cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X); | ||
1583 | cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y); | ||
1584 | cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z); | ||
1585 | |||
1586 | Quaternion sitTargetOrient = prim.SitTargetOrientationLL; | ||
1587 | cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W); | ||
1588 | cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X); | ||
1589 | cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y); | ||
1590 | cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z); | ||
1591 | |||
1592 | cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]); | ||
1593 | cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]); | ||
1594 | cmd.Parameters.AddWithValue("PayButton2", prim.PayPrice[2]); | ||
1595 | cmd.Parameters.AddWithValue("PayButton3", prim.PayPrice[3]); | ||
1596 | cmd.Parameters.AddWithValue("PayButton4", prim.PayPrice[4]); | ||
1597 | |||
1598 | if ((prim.SoundFlags & 1) != 0) // Looped | ||
1599 | { | ||
1600 | cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString()); | ||
1601 | cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain); | ||
1602 | } | ||
1603 | else | ||
1604 | { | ||
1605 | cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero); | ||
1606 | cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f); | ||
1607 | } | ||
1608 | |||
1609 | cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation); | ||
1610 | cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem); | ||
1611 | |||
1612 | cmd.Parameters.AddWithValue("OmegaX", (double)prim.AngularVelocity.X); | ||
1613 | cmd.Parameters.AddWithValue("OmegaY", (double)prim.AngularVelocity.Y); | ||
1614 | cmd.Parameters.AddWithValue("OmegaZ", (double)prim.AngularVelocity.Z); | ||
1615 | |||
1616 | cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X); | ||
1617 | cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y); | ||
1618 | cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z); | ||
1619 | |||
1620 | cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X); | ||
1621 | cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y); | ||
1622 | cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z); | ||
1623 | |||
1624 | if (prim.GetForceMouselook()) | ||
1625 | cmd.Parameters.AddWithValue("ForceMouselook", 1); | ||
1626 | else | ||
1627 | cmd.Parameters.AddWithValue("ForceMouselook", 0); | ||
1628 | |||
1629 | cmd.Parameters.AddWithValue("ScriptAccessPin", prim.ScriptAccessPin); | ||
1630 | |||
1631 | if (prim.AllowedDrop) | ||
1632 | cmd.Parameters.AddWithValue("AllowedDrop", 1); | ||
1633 | else | ||
1634 | cmd.Parameters.AddWithValue("AllowedDrop", 0); | ||
1635 | |||
1636 | if (prim.DIE_AT_EDGE) | ||
1637 | cmd.Parameters.AddWithValue("DieAtEdge", 1); | ||
1638 | else | ||
1639 | cmd.Parameters.AddWithValue("DieAtEdge", 0); | ||
1640 | |||
1641 | cmd.Parameters.AddWithValue("SalePrice", prim.SalePrice); | ||
1642 | cmd.Parameters.AddWithValue("SaleType", unchecked((sbyte)(prim.ObjectSaleType))); | ||
1643 | |||
1644 | byte clickAction = prim.ClickAction; | ||
1645 | cmd.Parameters.AddWithValue("ClickAction", unchecked((sbyte)(clickAction))); | ||
1646 | |||
1647 | cmd.Parameters.AddWithValue("Material", unchecked((sbyte)(prim.Material))); | ||
1648 | |||
1649 | cmd.Parameters.AddWithValue("CollisionSound", prim.CollisionSound.ToString()); | ||
1650 | cmd.Parameters.AddWithValue("CollisionSoundVolume", prim.CollisionSoundVolume); | ||
1651 | |||
1652 | if (prim.PassTouches) | ||
1653 | cmd.Parameters.AddWithValue("PassTouches", 1); | ||
1654 | else | ||
1655 | cmd.Parameters.AddWithValue("PassTouches", 0); | ||
1656 | |||
1657 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); | ||
1658 | cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); | ||
1659 | if (prim.AttachedPos != null) | ||
1660 | { | ||
1661 | cmd.Parameters.AddWithValue("AttachedPosX", (double)prim.AttachedPos.X); | ||
1662 | cmd.Parameters.AddWithValue("AttachedPosY", (double)prim.AttachedPos.Y); | ||
1663 | cmd.Parameters.AddWithValue("AttachedPosZ", (double)prim.AttachedPos.Z); | ||
1664 | } | ||
1665 | |||
1666 | if (prim.KeyframeMotion != null) | ||
1667 | cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize()); | ||
1668 | else | ||
1669 | cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); | ||
1670 | |||
1671 | if (prim.DynAttrs.CountNamespaces > 0) | ||
1672 | cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml()); | ||
1673 | else | ||
1674 | cmd.Parameters.AddWithValue("DynAttrs", null); | ||
1675 | |||
1676 | cmd.Parameters.AddWithValue("PhysicsShapeType", prim.PhysicsShapeType); | ||
1677 | cmd.Parameters.AddWithValue("Density", (double)prim.Density); | ||
1678 | cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier); | ||
1679 | cmd.Parameters.AddWithValue("Friction", (double)prim.Friction); | ||
1680 | cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution); | ||
1681 | } | ||
1682 | |||
1683 | /// <summary> | ||
1684 | /// | ||
1685 | /// </summary> | ||
1686 | /// <param name="row"></param> | ||
1687 | /// <param name="taskItem"></param> | ||
1688 | private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem) | ||
1689 | { | ||
1690 | cmd.Parameters.AddWithValue("itemID", taskItem.ItemID); | ||
1691 | cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID); | ||
1692 | cmd.Parameters.AddWithValue("assetID", taskItem.AssetID); | ||
1693 | cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID); | ||
1694 | |||
1695 | cmd.Parameters.AddWithValue("invType", taskItem.InvType); | ||
1696 | cmd.Parameters.AddWithValue("assetType", taskItem.Type); | ||
1697 | |||
1698 | cmd.Parameters.AddWithValue("name", taskItem.Name); | ||
1699 | cmd.Parameters.AddWithValue("description", taskItem.Description); | ||
1700 | cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate); | ||
1701 | cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorIdentification); | ||
1702 | cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID); | ||
1703 | cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID); | ||
1704 | cmd.Parameters.AddWithValue("groupID", taskItem.GroupID); | ||
1705 | cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions); | ||
1706 | cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions); | ||
1707 | cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions); | ||
1708 | cmd.Parameters.AddWithValue("everyonePermissions", taskItem.EveryonePermissions); | ||
1709 | cmd.Parameters.AddWithValue("groupPermissions", taskItem.GroupPermissions); | ||
1710 | cmd.Parameters.AddWithValue("flags", taskItem.Flags); | ||
1711 | } | ||
1712 | |||
1713 | /// <summary> | ||
1714 | /// | ||
1715 | /// </summary> | ||
1716 | private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings settings) | ||
1717 | { | ||
1718 | cmd.Parameters.AddWithValue("RegionUUID", settings.RegionUUID.ToString()); | ||
1719 | cmd.Parameters.AddWithValue("BlockTerraform", settings.BlockTerraform); | ||
1720 | cmd.Parameters.AddWithValue("BlockFly", settings.BlockFly); | ||
1721 | cmd.Parameters.AddWithValue("AllowDamage", settings.AllowDamage); | ||
1722 | cmd.Parameters.AddWithValue("RestrictPushing", settings.RestrictPushing); | ||
1723 | cmd.Parameters.AddWithValue("AllowLandResell", settings.AllowLandResell); | ||
1724 | cmd.Parameters.AddWithValue("AllowLandJoinDivide", settings.AllowLandJoinDivide); | ||
1725 | cmd.Parameters.AddWithValue("BlockShowInSearch", settings.BlockShowInSearch); | ||
1726 | cmd.Parameters.AddWithValue("AgentLimit", settings.AgentLimit); | ||
1727 | cmd.Parameters.AddWithValue("ObjectBonus", settings.ObjectBonus); | ||
1728 | cmd.Parameters.AddWithValue("Maturity", settings.Maturity); | ||
1729 | cmd.Parameters.AddWithValue("DisableScripts", settings.DisableScripts); | ||
1730 | cmd.Parameters.AddWithValue("DisableCollisions", settings.DisableCollisions); | ||
1731 | cmd.Parameters.AddWithValue("DisablePhysics", settings.DisablePhysics); | ||
1732 | cmd.Parameters.AddWithValue("TerrainTexture1", settings.TerrainTexture1.ToString()); | ||
1733 | cmd.Parameters.AddWithValue("TerrainTexture2", settings.TerrainTexture2.ToString()); | ||
1734 | cmd.Parameters.AddWithValue("TerrainTexture3", settings.TerrainTexture3.ToString()); | ||
1735 | cmd.Parameters.AddWithValue("TerrainTexture4", settings.TerrainTexture4.ToString()); | ||
1736 | cmd.Parameters.AddWithValue("Elevation1NW", settings.Elevation1NW); | ||
1737 | cmd.Parameters.AddWithValue("Elevation2NW", settings.Elevation2NW); | ||
1738 | cmd.Parameters.AddWithValue("Elevation1NE", settings.Elevation1NE); | ||
1739 | cmd.Parameters.AddWithValue("Elevation2NE", settings.Elevation2NE); | ||
1740 | cmd.Parameters.AddWithValue("Elevation1SE", settings.Elevation1SE); | ||
1741 | cmd.Parameters.AddWithValue("Elevation2SE", settings.Elevation2SE); | ||
1742 | cmd.Parameters.AddWithValue("Elevation1SW", settings.Elevation1SW); | ||
1743 | cmd.Parameters.AddWithValue("Elevation2SW", settings.Elevation2SW); | ||
1744 | cmd.Parameters.AddWithValue("WaterHeight", settings.WaterHeight); | ||
1745 | cmd.Parameters.AddWithValue("TerrainRaiseLimit", settings.TerrainRaiseLimit); | ||
1746 | cmd.Parameters.AddWithValue("TerrainLowerLimit", settings.TerrainLowerLimit); | ||
1747 | cmd.Parameters.AddWithValue("UseEstateSun", settings.UseEstateSun); | ||
1748 | cmd.Parameters.AddWithValue("Sandbox", settings.Sandbox); | ||
1749 | cmd.Parameters.AddWithValue("SunVectorX", settings.SunVector.X); | ||
1750 | cmd.Parameters.AddWithValue("SunVectorY", settings.SunVector.Y); | ||
1751 | cmd.Parameters.AddWithValue("SunVectorZ", settings.SunVector.Z); | ||
1752 | cmd.Parameters.AddWithValue("FixedSun", settings.FixedSun); | ||
1753 | cmd.Parameters.AddWithValue("SunPosition", settings.SunPosition); | ||
1754 | cmd.Parameters.AddWithValue("Covenant", settings.Covenant.ToString()); | ||
1755 | cmd.Parameters.AddWithValue("CovenantChangedDateTime", settings.CovenantChangedDateTime); | ||
1756 | cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); | ||
1757 | cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); | ||
1758 | cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID); | ||
1759 | |||
1760 | cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID); | ||
1761 | cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject); | ||
1762 | } | ||
1763 | |||
1764 | /// <summary> | ||
1765 | /// | ||
1766 | /// </summary> | ||
1767 | /// <param name="row"></param> | ||
1768 | /// <param name="land"></param> | ||
1769 | /// <param name="regionUUID"></param> | ||
1770 | private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID regionUUID) | ||
1771 | { | ||
1772 | cmd.Parameters.AddWithValue("UUID", land.GlobalID.ToString()); | ||
1773 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1774 | cmd.Parameters.AddWithValue("LocalLandID", land.LocalID); | ||
1775 | |||
1776 | // Bitmap is a byte[512] | ||
1777 | cmd.Parameters.AddWithValue("Bitmap", land.Bitmap); | ||
1778 | |||
1779 | cmd.Parameters.AddWithValue("Name", land.Name); | ||
1780 | cmd.Parameters.AddWithValue("Description", land.Description); | ||
1781 | cmd.Parameters.AddWithValue("OwnerUUID", land.OwnerID.ToString()); | ||
1782 | cmd.Parameters.AddWithValue("IsGroupOwned", land.IsGroupOwned); | ||
1783 | cmd.Parameters.AddWithValue("Area", land.Area); | ||
1784 | cmd.Parameters.AddWithValue("AuctionID", land.AuctionID); //Unemplemented | ||
1785 | cmd.Parameters.AddWithValue("Category", land.Category); //Enum libsecondlife.Parcel.ParcelCategory | ||
1786 | cmd.Parameters.AddWithValue("ClaimDate", land.ClaimDate); | ||
1787 | cmd.Parameters.AddWithValue("ClaimPrice", land.ClaimPrice); | ||
1788 | cmd.Parameters.AddWithValue("GroupUUID", land.GroupID.ToString()); | ||
1789 | cmd.Parameters.AddWithValue("SalePrice", land.SalePrice); | ||
1790 | cmd.Parameters.AddWithValue("LandStatus", land.Status); //Enum. libsecondlife.Parcel.ParcelStatus | ||
1791 | cmd.Parameters.AddWithValue("LandFlags", land.Flags); | ||
1792 | cmd.Parameters.AddWithValue("LandingType", land.LandingType); | ||
1793 | cmd.Parameters.AddWithValue("MediaAutoScale", land.MediaAutoScale); | ||
1794 | cmd.Parameters.AddWithValue("MediaTextureUUID", land.MediaID.ToString()); | ||
1795 | cmd.Parameters.AddWithValue("MediaURL", land.MediaURL); | ||
1796 | cmd.Parameters.AddWithValue("MusicURL", land.MusicURL); | ||
1797 | cmd.Parameters.AddWithValue("PassHours", land.PassHours); | ||
1798 | cmd.Parameters.AddWithValue("PassPrice", land.PassPrice); | ||
1799 | cmd.Parameters.AddWithValue("SnapshotUUID", land.SnapshotID.ToString()); | ||
1800 | cmd.Parameters.AddWithValue("UserLocationX", land.UserLocation.X); | ||
1801 | cmd.Parameters.AddWithValue("UserLocationY", land.UserLocation.Y); | ||
1802 | cmd.Parameters.AddWithValue("UserLocationZ", land.UserLocation.Z); | ||
1803 | cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X); | ||
1804 | cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y); | ||
1805 | cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); | ||
1806 | cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); | ||
1807 | cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); | ||
1808 | cmd.Parameters.AddWithValue("Dwell", land.Dwell); | ||
1809 | cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription); | ||
1810 | cmd.Parameters.AddWithValue("MediaType", land.MediaType); | ||
1811 | cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth); | ||
1812 | cmd.Parameters.AddWithValue("MediaHeight", land.MediaHeight); | ||
1813 | cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop); | ||
1814 | cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic); | ||
1815 | cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia); | ||
1816 | } | ||
1817 | |||
1818 | /// <summary> | ||
1819 | /// | ||
1820 | /// </summary> | ||
1821 | /// <param name="row"></param> | ||
1822 | /// <param name="entry"></param> | ||
1823 | /// <param name="parcelID"></param> | ||
1824 | private static void FillLandAccessCommand(MySqlCommand cmd, LandAccessEntry entry, UUID parcelID) | ||
1825 | { | ||
1826 | cmd.Parameters.AddWithValue("LandUUID", parcelID.ToString()); | ||
1827 | cmd.Parameters.AddWithValue("AccessUUID", entry.AgentID.ToString()); | ||
1828 | cmd.Parameters.AddWithValue("Flags", entry.Flags); | ||
1829 | cmd.Parameters.AddWithValue("Expires", entry.Expires.ToString()); | ||
1830 | } | ||
1831 | |||
1832 | /// <summary> | ||
1833 | /// | ||
1834 | /// </summary> | ||
1835 | /// <param name="row"></param> | ||
1836 | /// <returns></returns> | ||
1837 | private PrimitiveBaseShape BuildShape(IDataReader row) | ||
1838 | { | ||
1839 | PrimitiveBaseShape s = new PrimitiveBaseShape(); | ||
1840 | s.Scale = new Vector3( | ||
1841 | (float)(double)row["ScaleX"], | ||
1842 | (float)(double)row["ScaleY"], | ||
1843 | (float)(double)row["ScaleZ"] | ||
1844 | ); | ||
1845 | // paths | ||
1846 | s.PCode = (byte)(int)row["PCode"]; | ||
1847 | s.PathBegin = (ushort)(int)row["PathBegin"]; | ||
1848 | s.PathEnd = (ushort)(int)row["PathEnd"]; | ||
1849 | s.PathScaleX = (byte)(int)row["PathScaleX"]; | ||
1850 | s.PathScaleY = (byte)(int)row["PathScaleY"]; | ||
1851 | s.PathShearX = (byte)(int)row["PathShearX"]; | ||
1852 | s.PathShearY = (byte)(int)row["PathShearY"]; | ||
1853 | s.PathSkew = (sbyte)(int)row["PathSkew"]; | ||
1854 | s.PathCurve = (byte)(int)row["PathCurve"]; | ||
1855 | s.PathRadiusOffset = (sbyte)(int)row["PathRadiusOffset"]; | ||
1856 | s.PathRevolutions = (byte)(int)row["PathRevolutions"]; | ||
1857 | s.PathTaperX = (sbyte)(int)row["PathTaperX"]; | ||
1858 | s.PathTaperY = (sbyte)(int)row["PathTaperY"]; | ||
1859 | s.PathTwist = (sbyte)(int)row["PathTwist"]; | ||
1860 | s.PathTwistBegin = (sbyte)(int)row["PathTwistBegin"]; | ||
1861 | // profile | ||
1862 | s.ProfileBegin = (ushort)(int)row["ProfileBegin"]; | ||
1863 | s.ProfileEnd = (ushort)(int)row["ProfileEnd"]; | ||
1864 | s.ProfileCurve = (byte)(int)row["ProfileCurve"]; | ||
1865 | s.ProfileHollow = (ushort)(int)row["ProfileHollow"]; | ||
1866 | s.TextureEntry = (byte[])row["Texture"]; | ||
1867 | |||
1868 | s.ExtraParams = (byte[])row["ExtraParams"]; | ||
1869 | |||
1870 | s.State = (byte)(int)row["State"]; | ||
1871 | s.LastAttachPoint = (byte)(int)row["LastAttachPoint"]; | ||
1872 | |||
1873 | if (!(row["Media"] is System.DBNull)) | ||
1874 | s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); | ||
1875 | |||
1876 | return s; | ||
1877 | } | ||
1878 | |||
1879 | /// <summary> | ||
1880 | /// | ||
1881 | /// </summary> | ||
1882 | /// <param name="row"></param> | ||
1883 | /// <param name="prim"></param> | ||
1884 | private void FillShapeCommand(MySqlCommand cmd, SceneObjectPart prim) | ||
1885 | { | ||
1886 | PrimitiveBaseShape s = prim.Shape; | ||
1887 | cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); | ||
1888 | // shape is an enum | ||
1889 | cmd.Parameters.AddWithValue("Shape", 0); | ||
1890 | // vectors | ||
1891 | cmd.Parameters.AddWithValue("ScaleX", (double)s.Scale.X); | ||
1892 | cmd.Parameters.AddWithValue("ScaleY", (double)s.Scale.Y); | ||
1893 | cmd.Parameters.AddWithValue("ScaleZ", (double)s.Scale.Z); | ||
1894 | // paths | ||
1895 | cmd.Parameters.AddWithValue("PCode", s.PCode); | ||
1896 | cmd.Parameters.AddWithValue("PathBegin", s.PathBegin); | ||
1897 | cmd.Parameters.AddWithValue("PathEnd", s.PathEnd); | ||
1898 | cmd.Parameters.AddWithValue("PathScaleX", s.PathScaleX); | ||
1899 | cmd.Parameters.AddWithValue("PathScaleY", s.PathScaleY); | ||
1900 | cmd.Parameters.AddWithValue("PathShearX", s.PathShearX); | ||
1901 | cmd.Parameters.AddWithValue("PathShearY", s.PathShearY); | ||
1902 | cmd.Parameters.AddWithValue("PathSkew", s.PathSkew); | ||
1903 | cmd.Parameters.AddWithValue("PathCurve", s.PathCurve); | ||
1904 | cmd.Parameters.AddWithValue("PathRadiusOffset", s.PathRadiusOffset); | ||
1905 | cmd.Parameters.AddWithValue("PathRevolutions", s.PathRevolutions); | ||
1906 | cmd.Parameters.AddWithValue("PathTaperX", s.PathTaperX); | ||
1907 | cmd.Parameters.AddWithValue("PathTaperY", s.PathTaperY); | ||
1908 | cmd.Parameters.AddWithValue("PathTwist", s.PathTwist); | ||
1909 | cmd.Parameters.AddWithValue("PathTwistBegin", s.PathTwistBegin); | ||
1910 | // profile | ||
1911 | cmd.Parameters.AddWithValue("ProfileBegin", s.ProfileBegin); | ||
1912 | cmd.Parameters.AddWithValue("ProfileEnd", s.ProfileEnd); | ||
1913 | cmd.Parameters.AddWithValue("ProfileCurve", s.ProfileCurve); | ||
1914 | cmd.Parameters.AddWithValue("ProfileHollow", s.ProfileHollow); | ||
1915 | cmd.Parameters.AddWithValue("Texture", s.TextureEntry); | ||
1916 | cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); | ||
1917 | cmd.Parameters.AddWithValue("State", s.State); | ||
1918 | cmd.Parameters.AddWithValue("LastAttachPoint", s.LastAttachPoint); | ||
1919 | cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); | ||
1920 | } | ||
1921 | |||
1922 | public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) | ||
1923 | { | ||
1924 | lock (m_dbLock) | ||
1925 | { | ||
1926 | RemoveItems(primID); | ||
1927 | |||
1928 | if (items.Count == 0) | ||
1929 | return; | ||
1930 | |||
1931 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1932 | { | ||
1933 | dbcon.Open(); | ||
1934 | |||
1935 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1936 | { | ||
1937 | cmd.CommandText = "insert into primitems (" + | ||
1938 | "invType, assetType, name, " + | ||
1939 | "description, creationDate, nextPermissions, " + | ||
1940 | "currentPermissions, basePermissions, " + | ||
1941 | "everyonePermissions, groupPermissions, " + | ||
1942 | "flags, itemID, primID, assetID, " + | ||
1943 | "parentFolderID, creatorID, ownerID, " + | ||
1944 | "groupID, lastOwnerID) values (?invType, " + | ||
1945 | "?assetType, ?name, ?description, " + | ||
1946 | "?creationDate, ?nextPermissions, " + | ||
1947 | "?currentPermissions, ?basePermissions, " + | ||
1948 | "?everyonePermissions, ?groupPermissions, " + | ||
1949 | "?flags, ?itemID, ?primID, ?assetID, " + | ||
1950 | "?parentFolderID, ?creatorID, ?ownerID, " + | ||
1951 | "?groupID, ?lastOwnerID)"; | ||
1952 | |||
1953 | foreach (TaskInventoryItem item in items) | ||
1954 | { | ||
1955 | cmd.Parameters.Clear(); | ||
1956 | |||
1957 | FillItemCommand(cmd, item); | ||
1958 | |||
1959 | ExecuteNonQuery(cmd); | ||
1960 | } | ||
1961 | } | ||
1962 | } | ||
1963 | } | ||
1964 | } | ||
1965 | |||
1966 | private void LoadSpawnPoints(RegionSettings rs) | ||
1967 | { | ||
1968 | rs.ClearSpawnPoints(); | ||
1969 | |||
1970 | lock (m_dbLock) | ||
1971 | { | ||
1972 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1973 | { | ||
1974 | dbcon.Open(); | ||
1975 | |||
1976 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1977 | { | ||
1978 | cmd.CommandText = "select Yaw, Pitch, Distance from spawn_points where RegionID = ?RegionID"; | ||
1979 | cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString()); | ||
1980 | |||
1981 | using (IDataReader r = cmd.ExecuteReader()) | ||
1982 | { | ||
1983 | while (r.Read()) | ||
1984 | { | ||
1985 | SpawnPoint sp = new SpawnPoint(); | ||
1986 | |||
1987 | sp.Yaw = (float)r["Yaw"]; | ||
1988 | sp.Pitch = (float)r["Pitch"]; | ||
1989 | sp.Distance = (float)r["Distance"]; | ||
1990 | |||
1991 | rs.AddSpawnPoint(sp); | ||
1992 | } | ||
1993 | } | ||
1994 | } | ||
1995 | } | ||
1996 | } | ||
1997 | } | ||
1998 | |||
1999 | private void SaveSpawnPoints(RegionSettings rs) | ||
2000 | { | ||
2001 | lock (m_dbLock) | ||
2002 | { | ||
2003 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2004 | { | ||
2005 | dbcon.Open(); | ||
2006 | |||
2007 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2008 | { | ||
2009 | cmd.CommandText = "delete from spawn_points where RegionID = ?RegionID"; | ||
2010 | cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString()); | ||
2011 | |||
2012 | cmd.ExecuteNonQuery(); | ||
2013 | |||
2014 | cmd.Parameters.Clear(); | ||
2015 | |||
2016 | cmd.CommandText = "insert into spawn_points (RegionID, Yaw, Pitch, Distance) values ( ?RegionID, ?Yaw, ?Pitch, ?Distance)"; | ||
2017 | |||
2018 | foreach (SpawnPoint p in rs.SpawnPoints()) | ||
2019 | { | ||
2020 | cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString()); | ||
2021 | cmd.Parameters.AddWithValue("?Yaw", p.Yaw); | ||
2022 | cmd.Parameters.AddWithValue("?Pitch", p.Pitch); | ||
2023 | cmd.Parameters.AddWithValue("?Distance", p.Distance); | ||
2024 | |||
2025 | cmd.ExecuteNonQuery(); | ||
2026 | cmd.Parameters.Clear(); | ||
2027 | } | ||
2028 | } | ||
2029 | } | ||
2030 | } | ||
2031 | } | ||
2032 | |||
2033 | public void SaveExtra(UUID regionID, string name, string val) | ||
2034 | { | ||
2035 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2036 | { | ||
2037 | dbcon.Open(); | ||
2038 | |||
2039 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2040 | { | ||
2041 | cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)"; | ||
2042 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
2043 | cmd.Parameters.AddWithValue("?Name", name); | ||
2044 | cmd.Parameters.AddWithValue("?value", val); | ||
2045 | |||
2046 | cmd.ExecuteNonQuery(); | ||
2047 | } | ||
2048 | } | ||
2049 | } | ||
2050 | |||
2051 | public void RemoveExtra(UUID regionID, string name) | ||
2052 | { | ||
2053 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2054 | { | ||
2055 | dbcon.Open(); | ||
2056 | |||
2057 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2058 | { | ||
2059 | cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name"; | ||
2060 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
2061 | cmd.Parameters.AddWithValue("?Name", name); | ||
2062 | |||
2063 | cmd.ExecuteNonQuery(); | ||
2064 | } | ||
2065 | } | ||
2066 | } | ||
2067 | |||
2068 | public Dictionary<string, string> GetExtra(UUID regionID) | ||
2069 | { | ||
2070 | Dictionary<string, string> ret = new Dictionary<string, string>(); | ||
2071 | |||
2072 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2073 | { | ||
2074 | dbcon.Open(); | ||
2075 | |||
2076 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2077 | { | ||
2078 | cmd.CommandText = "select * from regionextra where RegionID=?RegionID"; | ||
2079 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
2080 | using (IDataReader r = cmd.ExecuteReader()) | ||
2081 | { | ||
2082 | while (r.Read()) | ||
2083 | { | ||
2084 | ret[r["Name"].ToString()] = r["value"].ToString(); | ||
2085 | } | ||
2086 | } | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | return ret; | ||
2091 | } | ||
2092 | } | ||
2093 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs new file mode 100644 index 0000000..e964295 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using MySql.Data.MySqlClient; | ||
35 | |||
36 | namespace 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 | for (int i = 0 ; i < words.Length ; i++) | ||
50 | { | ||
51 | if (words[i].Length < 3) | ||
52 | { | ||
53 | if (i != words.Length - 1) | ||
54 | Array.Copy(words, i + 1, words, i, words.Length - i - 1); | ||
55 | Array.Resize(ref words, words.Length - 1); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (words.Length == 0) | ||
60 | return new UserAccountData[0]; | ||
61 | |||
62 | if (words.Length > 2) | ||
63 | return new UserAccountData[0]; | ||
64 | |||
65 | using (MySqlCommand cmd = new MySqlCommand()) | ||
66 | { | ||
67 | if (words.Length == 1) | ||
68 | { | ||
69 | cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm); | ||
70 | cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%"); | ||
71 | cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm); | ||
76 | cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%"); | ||
77 | cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%"); | ||
78 | cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); | ||
79 | } | ||
80 | |||
81 | return DoQuery(cmd); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs new file mode 100644 index 0000000..b35595d --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs | |||
@@ -0,0 +1,1086 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Data; | ||
30 | using System.Reflection; | ||
31 | using OpenSim.Data; | ||
32 | using OpenSim.Framework; | ||
33 | using MySql.Data.MySqlClient; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.StructuredData; | ||
36 | using log4net; | ||
37 | |||
38 | namespace 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 | } | ||
73 | } | ||
74 | #endregion Member Functions | ||
75 | |||
76 | #region Classifieds Queries | ||
77 | /// <summary> | ||
78 | /// Gets the classified records. | ||
79 | /// </summary> | ||
80 | /// <returns> | ||
81 | /// Array of classified records | ||
82 | /// </returns> | ||
83 | /// <param name='creatorId'> | ||
84 | /// Creator identifier. | ||
85 | /// </param> | ||
86 | public OSDArray GetClassifiedRecords(UUID creatorId) | ||
87 | { | ||
88 | OSDArray data = new OSDArray(); | ||
89 | |||
90 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
91 | { | ||
92 | string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; | ||
93 | dbcon.Open(); | ||
94 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
95 | { | ||
96 | cmd.Parameters.AddWithValue("?Id", creatorId); | ||
97 | using( MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) | ||
98 | { | ||
99 | if(reader.HasRows) | ||
100 | { | ||
101 | while (reader.Read()) | ||
102 | { | ||
103 | OSDMap n = new OSDMap(); | ||
104 | UUID Id = UUID.Zero; | ||
105 | |||
106 | string Name = null; | ||
107 | try | ||
108 | { | ||
109 | UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id); | ||
110 | Name = Convert.ToString(reader["name"]); | ||
111 | } | ||
112 | catch (Exception e) | ||
113 | { | ||
114 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
115 | ": UserAccount 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 | } | ||
125 | return data; | ||
126 | } | ||
127 | |||
128 | public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) | ||
129 | { | ||
130 | string query = string.Empty; | ||
131 | |||
132 | |||
133 | query += "INSERT INTO classifieds ("; | ||
134 | query += "`classifieduuid`,"; | ||
135 | query += "`creatoruuid`,"; | ||
136 | query += "`creationdate`,"; | ||
137 | query += "`expirationdate`,"; | ||
138 | query += "`category`,"; | ||
139 | query += "`name`,"; | ||
140 | query += "`description`,"; | ||
141 | query += "`parceluuid`,"; | ||
142 | query += "`parentestate`,"; | ||
143 | query += "`snapshotuuid`,"; | ||
144 | query += "`simname`,"; | ||
145 | query += "`posglobal`,"; | ||
146 | query += "`parcelname`,"; | ||
147 | query += "`classifiedflags`,"; | ||
148 | query += "`priceforlisting`) "; | ||
149 | query += "VALUES ("; | ||
150 | query += "?ClassifiedId,"; | ||
151 | query += "?CreatorId,"; | ||
152 | query += "?CreatedDate,"; | ||
153 | query += "?ExpirationDate,"; | ||
154 | query += "?Category,"; | ||
155 | query += "?Name,"; | ||
156 | query += "?Description,"; | ||
157 | query += "?ParcelId,"; | ||
158 | query += "?ParentEstate,"; | ||
159 | query += "?SnapshotId,"; | ||
160 | query += "?SimName,"; | ||
161 | query += "?GlobalPos,"; | ||
162 | query += "?ParcelName,"; | ||
163 | query += "?Flags,"; | ||
164 | query += "?ListingPrice ) "; | ||
165 | query += "ON DUPLICATE KEY UPDATE "; | ||
166 | query += "category=?Category, "; | ||
167 | query += "expirationdate=?ExpirationDate, "; | ||
168 | query += "name=?Name, "; | ||
169 | query += "description=?Description, "; | ||
170 | query += "parentestate=?ParentEstate, "; | ||
171 | query += "posglobal=?GlobalPos, "; | ||
172 | query += "parcelname=?ParcelName, "; | ||
173 | query += "classifiedflags=?Flags, "; | ||
174 | query += "priceforlisting=?ListingPrice, "; | ||
175 | query += "snapshotuuid=?SnapshotId"; | ||
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 | } | ||
232 | } | ||
233 | catch (Exception e) | ||
234 | { | ||
235 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
236 | ": ClassifiedesUpdate 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 | string query = string.Empty; | ||
246 | |||
247 | query += "DELETE FROM classifieds WHERE "; | ||
248 | query += "classifieduuid = ?recordId"; | ||
249 | |||
250 | try | ||
251 | { | ||
252 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
253 | { | ||
254 | dbcon.Open(); | ||
255 | |||
256 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
257 | { | ||
258 | cmd.Parameters.AddWithValue("?recordId", recordId.ToString()); | ||
259 | cmd.ExecuteNonQuery(); | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | catch (Exception e) | ||
264 | { | ||
265 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
266 | ": DeleteClassifiedRecord exception {0}", e.Message); | ||
267 | return false; | ||
268 | } | ||
269 | return true; | ||
270 | } | ||
271 | |||
272 | public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) | ||
273 | { | ||
274 | string query = string.Empty; | ||
275 | |||
276 | query += "SELECT * FROM classifieds WHERE "; | ||
277 | query += "classifieduuid = ?AdId"; | ||
278 | |||
279 | try | ||
280 | { | ||
281 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
282 | { | ||
283 | dbcon.Open(); | ||
284 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
285 | { | ||
286 | cmd.Parameters.AddWithValue("?AdId", ad.ClassifiedId.ToString()); | ||
287 | |||
288 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
289 | { | ||
290 | if(reader.Read ()) | ||
291 | { | ||
292 | ad.CreatorId = new UUID(reader.GetGuid("creatoruuid")); | ||
293 | ad.ParcelId = new UUID(reader.GetGuid("parceluuid")); | ||
294 | ad.SnapshotId = new UUID(reader.GetGuid("snapshotuuid")); | ||
295 | ad.CreationDate = Convert.ToInt32(reader["creationdate"]); | ||
296 | ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]); | ||
297 | ad.ParentEstate = Convert.ToInt32(reader["parentestate"]); | ||
298 | ad.Flags = (byte)reader.GetUInt32("classifiedflags"); | ||
299 | ad.Category = reader.GetInt32("category"); | ||
300 | ad.Price = reader.GetInt16("priceforlisting"); | ||
301 | ad.Name = reader.GetString("name"); | ||
302 | ad.Description = reader.GetString("description"); | ||
303 | ad.SimName = reader.GetString("simname"); | ||
304 | ad.GlobalPos = reader.GetString("posglobal"); | ||
305 | ad.ParcelName = reader.GetString("parcelname"); | ||
306 | |||
307 | } | ||
308 | } | ||
309 | } | ||
310 | dbcon.Close(); | ||
311 | } | ||
312 | } | ||
313 | catch (Exception e) | ||
314 | { | ||
315 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
316 | ": GetPickInfo exception {0}", e.Message); | ||
317 | } | ||
318 | return true; | ||
319 | } | ||
320 | #endregion Classifieds Queries | ||
321 | |||
322 | #region Picks Queries | ||
323 | public OSDArray GetAvatarPicks(UUID avatarId) | ||
324 | { | ||
325 | string query = string.Empty; | ||
326 | |||
327 | query += "SELECT `pickuuid`,`name` FROM userpicks WHERE "; | ||
328 | query += "creatoruuid = ?Id"; | ||
329 | OSDArray data = new OSDArray(); | ||
330 | |||
331 | try | ||
332 | { | ||
333 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
334 | { | ||
335 | dbcon.Open(); | ||
336 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
337 | { | ||
338 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
339 | |||
340 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
341 | { | ||
342 | if(reader.HasRows) | ||
343 | { | ||
344 | while (reader.Read()) | ||
345 | { | ||
346 | OSDMap record = new OSDMap(); | ||
347 | |||
348 | record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"])); | ||
349 | record.Add("name",OSD.FromString((string)reader["name"])); | ||
350 | data.Add(record); | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | catch (Exception e) | ||
358 | { | ||
359 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
360 | ": GetAvatarPicks exception {0}", e.Message); | ||
361 | } | ||
362 | return data; | ||
363 | } | ||
364 | |||
365 | public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) | ||
366 | { | ||
367 | string query = string.Empty; | ||
368 | UserProfilePick pick = new UserProfilePick(); | ||
369 | |||
370 | query += "SELECT * FROM userpicks WHERE "; | ||
371 | query += "creatoruuid = ?CreatorId AND "; | ||
372 | query += "pickuuid = ?PickId"; | ||
373 | |||
374 | try | ||
375 | { | ||
376 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
377 | { | ||
378 | dbcon.Open(); | ||
379 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
380 | { | ||
381 | cmd.Parameters.AddWithValue("?CreatorId", avatarId.ToString()); | ||
382 | cmd.Parameters.AddWithValue("?PickId", pickId.ToString()); | ||
383 | |||
384 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
385 | { | ||
386 | if(reader.HasRows) | ||
387 | { | ||
388 | reader.Read(); | ||
389 | |||
390 | string description = (string)reader["description"]; | ||
391 | |||
392 | if (string.IsNullOrEmpty(description)) | ||
393 | description = "No description given."; | ||
394 | |||
395 | UUID.TryParse((string)reader["pickuuid"], out pick.PickId); | ||
396 | UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId); | ||
397 | UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId); | ||
398 | UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId); | ||
399 | pick.GlobalPos = (string)reader["posglobal"]; | ||
400 | pick.Gatekeeper = (string)reader["gatekeeper"]; | ||
401 | bool.TryParse((string)reader["toppick"], out pick.TopPick); | ||
402 | bool.TryParse((string)reader["enabled"], out pick.Enabled); | ||
403 | pick.Name = (string)reader["name"]; | ||
404 | pick.Desc = description; | ||
405 | pick.ParcelName = (string)reader["user"]; | ||
406 | pick.OriginalName = (string)reader["originalname"]; | ||
407 | pick.SimName = (string)reader["simname"]; | ||
408 | pick.SortOrder = (int)reader["sortorder"]; | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | dbcon.Close(); | ||
413 | } | ||
414 | } | ||
415 | catch (Exception e) | ||
416 | { | ||
417 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
418 | ": GetPickInfo exception {0}", e.Message); | ||
419 | } | ||
420 | return pick; | ||
421 | } | ||
422 | |||
423 | public bool UpdatePicksRecord(UserProfilePick pick) | ||
424 | { | ||
425 | string query = string.Empty; | ||
426 | |||
427 | query += "INSERT INTO userpicks VALUES ("; | ||
428 | query += "?PickId,"; | ||
429 | query += "?CreatorId,"; | ||
430 | query += "?TopPick,"; | ||
431 | query += "?ParcelId,"; | ||
432 | query += "?Name,"; | ||
433 | query += "?Desc,"; | ||
434 | query += "?SnapshotId,"; | ||
435 | query += "?User,"; | ||
436 | query += "?Original,"; | ||
437 | query += "?SimName,"; | ||
438 | query += "?GlobalPos,"; | ||
439 | query += "?SortOrder,"; | ||
440 | query += "?Enabled,"; | ||
441 | query += "?Gatekeeper)"; | ||
442 | query += "ON DUPLICATE KEY UPDATE "; | ||
443 | query += "parceluuid=?ParcelId,"; | ||
444 | query += "name=?Name,"; | ||
445 | query += "description=?Desc,"; | ||
446 | query += "user=?User,"; | ||
447 | query += "simname=?SimName,"; | ||
448 | query += "snapshotuuid=?SnapshotId,"; | ||
449 | query += "pickuuid=?PickId,"; | ||
450 | query += "posglobal=?GlobalPos,"; | ||
451 | query += "gatekeeper=?Gatekeeper"; | ||
452 | |||
453 | try | ||
454 | { | ||
455 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
456 | { | ||
457 | dbcon.Open(); | ||
458 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
459 | { | ||
460 | cmd.Parameters.AddWithValue("?PickId", pick.PickId.ToString()); | ||
461 | cmd.Parameters.AddWithValue("?CreatorId", pick.CreatorId.ToString()); | ||
462 | cmd.Parameters.AddWithValue("?TopPick", pick.TopPick.ToString()); | ||
463 | cmd.Parameters.AddWithValue("?ParcelId", pick.ParcelId.ToString()); | ||
464 | cmd.Parameters.AddWithValue("?Name", pick.Name.ToString()); | ||
465 | cmd.Parameters.AddWithValue("?Desc", pick.Desc.ToString()); | ||
466 | cmd.Parameters.AddWithValue("?SnapshotId", pick.SnapshotId.ToString()); | ||
467 | cmd.Parameters.AddWithValue("?User", pick.ParcelName.ToString()); | ||
468 | cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString()); | ||
469 | cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString()); | ||
470 | cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos); | ||
471 | cmd.Parameters.AddWithValue("?Gatekeeper",pick.Gatekeeper); | ||
472 | cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ()); | ||
473 | cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString()); | ||
474 | |||
475 | cmd.ExecuteNonQuery(); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | catch (Exception e) | ||
480 | { | ||
481 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
482 | ": UpdateAvatarNotes exception {0}", e.Message); | ||
483 | return false; | ||
484 | } | ||
485 | return true; | ||
486 | } | ||
487 | |||
488 | public bool DeletePicksRecord(UUID pickId) | ||
489 | { | ||
490 | string query = string.Empty; | ||
491 | |||
492 | query += "DELETE FROM userpicks WHERE "; | ||
493 | query += "pickuuid = ?PickId"; | ||
494 | |||
495 | try | ||
496 | { | ||
497 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
498 | { | ||
499 | dbcon.Open(); | ||
500 | |||
501 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
502 | { | ||
503 | cmd.Parameters.AddWithValue("?PickId", pickId.ToString()); | ||
504 | |||
505 | cmd.ExecuteNonQuery(); | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | catch (Exception e) | ||
510 | { | ||
511 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
512 | ": DeleteUserPickRecord exception {0}", e.Message); | ||
513 | return false; | ||
514 | } | ||
515 | return true; | ||
516 | } | ||
517 | #endregion Picks Queries | ||
518 | |||
519 | #region Avatar Notes Queries | ||
520 | public bool GetAvatarNotes(ref UserProfileNotes notes) | ||
521 | { // WIP | ||
522 | string query = string.Empty; | ||
523 | |||
524 | query += "SELECT `notes` FROM usernotes WHERE "; | ||
525 | query += "useruuid = ?Id AND "; | ||
526 | query += "targetuuid = ?TargetId"; | ||
527 | OSDArray data = new OSDArray(); | ||
528 | |||
529 | try | ||
530 | { | ||
531 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
532 | { | ||
533 | dbcon.Open(); | ||
534 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
535 | { | ||
536 | cmd.Parameters.AddWithValue("?Id", notes.UserId.ToString()); | ||
537 | cmd.Parameters.AddWithValue("?TargetId", notes.TargetId.ToString()); | ||
538 | |||
539 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
540 | { | ||
541 | if(reader.HasRows) | ||
542 | { | ||
543 | reader.Read(); | ||
544 | notes.Notes = OSD.FromString((string)reader["notes"]); | ||
545 | } | ||
546 | else | ||
547 | { | ||
548 | notes.Notes = OSD.FromString(""); | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | } | ||
553 | } | ||
554 | catch (Exception e) | ||
555 | { | ||
556 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
557 | ": GetAvatarNotes exception {0}", e.Message); | ||
558 | } | ||
559 | return true; | ||
560 | } | ||
561 | |||
562 | public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) | ||
563 | { | ||
564 | string query = string.Empty; | ||
565 | bool remove; | ||
566 | |||
567 | if(string.IsNullOrEmpty(note.Notes)) | ||
568 | { | ||
569 | remove = true; | ||
570 | query += "DELETE FROM usernotes WHERE "; | ||
571 | query += "useruuid=?UserId AND "; | ||
572 | query += "targetuuid=?TargetId"; | ||
573 | } | ||
574 | else | ||
575 | { | ||
576 | remove = false; | ||
577 | query += "INSERT INTO usernotes VALUES ( "; | ||
578 | query += "?UserId,"; | ||
579 | query += "?TargetId,"; | ||
580 | query += "?Notes )"; | ||
581 | query += "ON DUPLICATE KEY "; | ||
582 | query += "UPDATE "; | ||
583 | query += "notes=?Notes"; | ||
584 | } | ||
585 | |||
586 | try | ||
587 | { | ||
588 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
589 | { | ||
590 | dbcon.Open(); | ||
591 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
592 | { | ||
593 | if(!remove) | ||
594 | cmd.Parameters.AddWithValue("?Notes", note.Notes); | ||
595 | cmd.Parameters.AddWithValue("?TargetId", note.TargetId.ToString ()); | ||
596 | cmd.Parameters.AddWithValue("?UserId", note.UserId.ToString()); | ||
597 | |||
598 | cmd.ExecuteNonQuery(); | ||
599 | } | ||
600 | } | ||
601 | } | ||
602 | catch (Exception e) | ||
603 | { | ||
604 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
605 | ": UpdateAvatarNotes exception {0}", e.Message); | ||
606 | return false; | ||
607 | } | ||
608 | return true; | ||
609 | |||
610 | } | ||
611 | #endregion Avatar Notes Queries | ||
612 | |||
613 | #region Avatar Properties | ||
614 | public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) | ||
615 | { | ||
616 | string query = string.Empty; | ||
617 | |||
618 | query += "SELECT * FROM userprofile WHERE "; | ||
619 | query += "useruuid = ?Id"; | ||
620 | |||
621 | try | ||
622 | { | ||
623 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
624 | { | ||
625 | dbcon.Open(); | ||
626 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
627 | { | ||
628 | cmd.Parameters.AddWithValue("?Id", props.UserId.ToString()); | ||
629 | |||
630 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
631 | { | ||
632 | if(reader.HasRows) | ||
633 | { | ||
634 | reader.Read(); | ||
635 | props.WebUrl = (string)reader["profileURL"]; | ||
636 | UUID.TryParse((string)reader["profileImage"], out props.ImageId); | ||
637 | props.AboutText = (string)reader["profileAboutText"]; | ||
638 | UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId); | ||
639 | props.FirstLifeText = (string)reader["profileFirstText"]; | ||
640 | UUID.TryParse((string)reader["profilePartner"], out props.PartnerId); | ||
641 | props.WantToMask = (int)reader["profileWantToMask"]; | ||
642 | props.WantToText = (string)reader["profileWantToText"]; | ||
643 | props.SkillsMask = (int)reader["profileSkillsMask"]; | ||
644 | props.SkillsText = (string)reader["profileSkillsText"]; | ||
645 | props.Language = (string)reader["profileLanguages"]; | ||
646 | } | ||
647 | else | ||
648 | { | ||
649 | props.WebUrl = string.Empty; | ||
650 | props.ImageId = UUID.Zero; | ||
651 | props.AboutText = string.Empty; | ||
652 | props.FirstLifeImageId = UUID.Zero; | ||
653 | props.FirstLifeText = string.Empty; | ||
654 | props.PartnerId = UUID.Zero; | ||
655 | props.WantToMask = 0; | ||
656 | props.WantToText = string.Empty; | ||
657 | props.SkillsMask = 0; | ||
658 | props.SkillsText = string.Empty; | ||
659 | props.Language = string.Empty; | ||
660 | props.PublishProfile = false; | ||
661 | props.PublishMature = false; | ||
662 | |||
663 | query = "INSERT INTO userprofile ("; | ||
664 | query += "useruuid, "; | ||
665 | query += "profilePartner, "; | ||
666 | query += "profileAllowPublish, "; | ||
667 | query += "profileMaturePublish, "; | ||
668 | query += "profileURL, "; | ||
669 | query += "profileWantToMask, "; | ||
670 | query += "profileWantToText, "; | ||
671 | query += "profileSkillsMask, "; | ||
672 | query += "profileSkillsText, "; | ||
673 | query += "profileLanguages, "; | ||
674 | query += "profileImage, "; | ||
675 | query += "profileAboutText, "; | ||
676 | query += "profileFirstImage, "; | ||
677 | query += "profileFirstText) VALUES ("; | ||
678 | query += "?userId, "; | ||
679 | query += "?profilePartner, "; | ||
680 | query += "?profileAllowPublish, "; | ||
681 | query += "?profileMaturePublish, "; | ||
682 | query += "?profileURL, "; | ||
683 | query += "?profileWantToMask, "; | ||
684 | query += "?profileWantToText, "; | ||
685 | query += "?profileSkillsMask, "; | ||
686 | query += "?profileSkillsText, "; | ||
687 | query += "?profileLanguages, "; | ||
688 | query += "?profileImage, "; | ||
689 | query += "?profileAboutText, "; | ||
690 | query += "?profileFirstImage, "; | ||
691 | query += "?profileFirstText)"; | ||
692 | |||
693 | dbcon.Close(); | ||
694 | dbcon.Open(); | ||
695 | |||
696 | using (MySqlCommand put = new MySqlCommand(query, dbcon)) | ||
697 | { | ||
698 | put.Parameters.AddWithValue("?userId", props.UserId.ToString()); | ||
699 | put.Parameters.AddWithValue("?profilePartner", props.PartnerId.ToString()); | ||
700 | put.Parameters.AddWithValue("?profileAllowPublish", props.PublishProfile); | ||
701 | put.Parameters.AddWithValue("?profileMaturePublish", props.PublishMature); | ||
702 | put.Parameters.AddWithValue("?profileURL", props.WebUrl); | ||
703 | put.Parameters.AddWithValue("?profileWantToMask", props.WantToMask); | ||
704 | put.Parameters.AddWithValue("?profileWantToText", props.WantToText); | ||
705 | put.Parameters.AddWithValue("?profileSkillsMask", props.SkillsMask); | ||
706 | put.Parameters.AddWithValue("?profileSkillsText", props.SkillsText); | ||
707 | put.Parameters.AddWithValue("?profileLanguages", props.Language); | ||
708 | put.Parameters.AddWithValue("?profileImage", props.ImageId.ToString()); | ||
709 | put.Parameters.AddWithValue("?profileAboutText", props.AboutText); | ||
710 | put.Parameters.AddWithValue("?profileFirstImage", props.FirstLifeImageId.ToString()); | ||
711 | put.Parameters.AddWithValue("?profileFirstText", props.FirstLifeText); | ||
712 | |||
713 | put.ExecuteNonQuery(); | ||
714 | } | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | } | ||
719 | } | ||
720 | catch (Exception e) | ||
721 | { | ||
722 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
723 | ": Requst properties exception {0}", e.Message); | ||
724 | result = e.Message; | ||
725 | return false; | ||
726 | } | ||
727 | return true; | ||
728 | } | ||
729 | |||
730 | public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) | ||
731 | { | ||
732 | string query = string.Empty; | ||
733 | |||
734 | query += "UPDATE userprofile SET "; | ||
735 | query += "profileURL=?profileURL, "; | ||
736 | query += "profileImage=?image, "; | ||
737 | query += "profileAboutText=?abouttext,"; | ||
738 | query += "profileFirstImage=?firstlifeimage,"; | ||
739 | query += "profileFirstText=?firstlifetext "; | ||
740 | query += "WHERE useruuid=?uuid"; | ||
741 | |||
742 | try | ||
743 | { | ||
744 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
745 | { | ||
746 | dbcon.Open(); | ||
747 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
748 | { | ||
749 | cmd.Parameters.AddWithValue("?profileURL", props.WebUrl); | ||
750 | cmd.Parameters.AddWithValue("?image", props.ImageId.ToString()); | ||
751 | cmd.Parameters.AddWithValue("?abouttext", props.AboutText); | ||
752 | cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString()); | ||
753 | cmd.Parameters.AddWithValue("?firstlifetext", props.FirstLifeText); | ||
754 | cmd.Parameters.AddWithValue("?uuid", props.UserId.ToString()); | ||
755 | |||
756 | cmd.ExecuteNonQuery(); | ||
757 | } | ||
758 | } | ||
759 | } | ||
760 | catch (Exception e) | ||
761 | { | ||
762 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
763 | ": AgentPropertiesUpdate exception {0}", e.Message); | ||
764 | |||
765 | return false; | ||
766 | } | ||
767 | return true; | ||
768 | } | ||
769 | #endregion Avatar Properties | ||
770 | |||
771 | #region Avatar Interests | ||
772 | public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) | ||
773 | { | ||
774 | string query = string.Empty; | ||
775 | |||
776 | query += "UPDATE userprofile SET "; | ||
777 | query += "profileWantToMask=?WantMask, "; | ||
778 | query += "profileWantToText=?WantText,"; | ||
779 | query += "profileSkillsMask=?SkillsMask,"; | ||
780 | query += "profileSkillsText=?SkillsText, "; | ||
781 | query += "profileLanguages=?Languages "; | ||
782 | query += "WHERE useruuid=?uuid"; | ||
783 | |||
784 | try | ||
785 | { | ||
786 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
787 | { | ||
788 | dbcon.Open(); | ||
789 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
790 | { | ||
791 | cmd.Parameters.AddWithValue("?WantMask", up.WantToMask); | ||
792 | cmd.Parameters.AddWithValue("?WantText", up.WantToText); | ||
793 | cmd.Parameters.AddWithValue("?SkillsMask", up.SkillsMask); | ||
794 | cmd.Parameters.AddWithValue("?SkillsText", up.SkillsText); | ||
795 | cmd.Parameters.AddWithValue("?Languages", up.Language); | ||
796 | cmd.Parameters.AddWithValue("?uuid", up.UserId.ToString()); | ||
797 | |||
798 | cmd.ExecuteNonQuery(); | ||
799 | } | ||
800 | } | ||
801 | } | ||
802 | catch (Exception e) | ||
803 | { | ||
804 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
805 | ": AgentInterestsUpdate exception {0}", e.Message); | ||
806 | result = e.Message; | ||
807 | return false; | ||
808 | } | ||
809 | return true; | ||
810 | } | ||
811 | #endregion Avatar Interests | ||
812 | |||
813 | public OSDArray GetUserImageAssets(UUID avatarId) | ||
814 | { | ||
815 | OSDArray data = new OSDArray(); | ||
816 | string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; | ||
817 | |||
818 | // Get classified image assets | ||
819 | |||
820 | |||
821 | try | ||
822 | { | ||
823 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
824 | { | ||
825 | dbcon.Open(); | ||
826 | |||
827 | using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`classifieds`"), dbcon)) | ||
828 | { | ||
829 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
830 | |||
831 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
832 | { | ||
833 | if(reader.HasRows) | ||
834 | { | ||
835 | while (reader.Read()) | ||
836 | { | ||
837 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString ())); | ||
838 | } | ||
839 | } | ||
840 | } | ||
841 | } | ||
842 | |||
843 | dbcon.Close(); | ||
844 | dbcon.Open(); | ||
845 | |||
846 | using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) | ||
847 | { | ||
848 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
849 | |||
850 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
851 | { | ||
852 | if(reader.HasRows) | ||
853 | { | ||
854 | while (reader.Read()) | ||
855 | { | ||
856 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString ())); | ||
857 | } | ||
858 | } | ||
859 | } | ||
860 | } | ||
861 | |||
862 | dbcon.Close(); | ||
863 | dbcon.Open(); | ||
864 | |||
865 | query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; | ||
866 | |||
867 | using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) | ||
868 | { | ||
869 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
870 | |||
871 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
872 | { | ||
873 | if(reader.HasRows) | ||
874 | { | ||
875 | while (reader.Read()) | ||
876 | { | ||
877 | data.Add(new OSDString((string)reader["profileImage"].ToString ())); | ||
878 | data.Add(new OSDString((string)reader["profileFirstImage"].ToString ())); | ||
879 | } | ||
880 | } | ||
881 | } | ||
882 | } | ||
883 | } | ||
884 | } | ||
885 | catch (Exception e) | ||
886 | { | ||
887 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
888 | ": GetAvatarNotes exception {0}", e.Message); | ||
889 | } | ||
890 | return data; | ||
891 | } | ||
892 | |||
893 | #region User Preferences | ||
894 | public bool GetUserPreferences(ref UserPreferences pref, ref string result) | ||
895 | { | ||
896 | string query = string.Empty; | ||
897 | |||
898 | query += "SELECT imviaemail,visible,email FROM "; | ||
899 | query += "usersettings WHERE "; | ||
900 | query += "useruuid = ?Id"; | ||
901 | |||
902 | OSDArray data = new OSDArray(); | ||
903 | |||
904 | try | ||
905 | { | ||
906 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
907 | { | ||
908 | dbcon.Open(); | ||
909 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
910 | { | ||
911 | cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString()); | ||
912 | |||
913 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
914 | { | ||
915 | if(reader.HasRows) | ||
916 | { | ||
917 | reader.Read(); | ||
918 | bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail); | ||
919 | bool.TryParse((string)reader["visible"], out pref.Visible); | ||
920 | pref.EMail = (string)reader["email"]; | ||
921 | } | ||
922 | else | ||
923 | { | ||
924 | dbcon.Close(); | ||
925 | dbcon.Open(); | ||
926 | |||
927 | query = "INSERT INTO usersettings VALUES "; | ||
928 | query += "(?uuid,'false','false', ?Email)"; | ||
929 | |||
930 | using (MySqlCommand put = new MySqlCommand(query, dbcon)) | ||
931 | { | ||
932 | |||
933 | put.Parameters.AddWithValue("?Email", pref.EMail); | ||
934 | put.Parameters.AddWithValue("?uuid", pref.UserId.ToString()); | ||
935 | |||
936 | put.ExecuteNonQuery(); | ||
937 | } | ||
938 | } | ||
939 | } | ||
940 | } | ||
941 | } | ||
942 | } | ||
943 | catch (Exception e) | ||
944 | { | ||
945 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
946 | ": Get preferences exception {0}", e.Message); | ||
947 | result = e.Message; | ||
948 | return false; | ||
949 | } | ||
950 | return true; | ||
951 | } | ||
952 | |||
953 | public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) | ||
954 | { | ||
955 | string query = string.Empty; | ||
956 | |||
957 | query += "UPDATE usersettings SET "; | ||
958 | query += "imviaemail=?ImViaEmail, "; | ||
959 | query += "visible=?Visible, "; | ||
960 | query += "email=?EMail "; | ||
961 | query += "WHERE useruuid=?uuid"; | ||
962 | |||
963 | try | ||
964 | { | ||
965 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
966 | { | ||
967 | dbcon.Open(); | ||
968 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
969 | { | ||
970 | cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower()); | ||
971 | cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower()); | ||
972 | cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString()); | ||
973 | cmd.Parameters.AddWithValue("?EMail", pref.EMail.ToString().ToLower()); | ||
974 | |||
975 | cmd.ExecuteNonQuery(); | ||
976 | } | ||
977 | } | ||
978 | } | ||
979 | catch (Exception e) | ||
980 | { | ||
981 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
982 | ": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException); | ||
983 | result = e.Message; | ||
984 | return false; | ||
985 | } | ||
986 | return true; | ||
987 | } | ||
988 | #endregion User Preferences | ||
989 | |||
990 | #region Integration | ||
991 | public bool GetUserAppData(ref UserAppData props, ref string result) | ||
992 | { | ||
993 | string query = string.Empty; | ||
994 | |||
995 | query += "SELECT * FROM `userdata` WHERE "; | ||
996 | query += "UserId = ?Id AND "; | ||
997 | query += "TagId = ?TagId"; | ||
998 | |||
999 | try | ||
1000 | { | ||
1001 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
1002 | { | ||
1003 | dbcon.Open(); | ||
1004 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
1005 | { | ||
1006 | cmd.Parameters.AddWithValue("?Id", props.UserId.ToString()); | ||
1007 | cmd.Parameters.AddWithValue ("?TagId", props.TagId.ToString()); | ||
1008 | |||
1009 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
1010 | { | ||
1011 | if(reader.HasRows) | ||
1012 | { | ||
1013 | reader.Read(); | ||
1014 | props.DataKey = (string)reader["DataKey"]; | ||
1015 | props.DataVal = (string)reader["DataVal"]; | ||
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | query += "INSERT INTO userdata VALUES ( "; | ||
1020 | query += "?UserId,"; | ||
1021 | query += "?TagId,"; | ||
1022 | query += "?DataKey,"; | ||
1023 | query += "?DataVal) "; | ||
1024 | |||
1025 | using (MySqlCommand put = new MySqlCommand(query, dbcon)) | ||
1026 | { | ||
1027 | put.Parameters.AddWithValue("?UserId", props.UserId.ToString()); | ||
1028 | put.Parameters.AddWithValue("?TagId", props.TagId.ToString()); | ||
1029 | put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString()); | ||
1030 | put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString()); | ||
1031 | |||
1032 | put.ExecuteNonQuery(); | ||
1033 | } | ||
1034 | } | ||
1035 | } | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | catch (Exception e) | ||
1040 | { | ||
1041 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
1042 | ": Requst application data exception {0}", e.Message); | ||
1043 | result = e.Message; | ||
1044 | return false; | ||
1045 | } | ||
1046 | return true; | ||
1047 | } | ||
1048 | |||
1049 | public bool SetUserAppData(UserAppData props, ref string result) | ||
1050 | { | ||
1051 | string query = string.Empty; | ||
1052 | |||
1053 | query += "UPDATE userdata SET "; | ||
1054 | query += "TagId = ?TagId, "; | ||
1055 | query += "DataKey = ?DataKey, "; | ||
1056 | query += "DataVal = ?DataVal WHERE "; | ||
1057 | query += "UserId = ?UserId AND "; | ||
1058 | query += "TagId = ?TagId"; | ||
1059 | |||
1060 | try | ||
1061 | { | ||
1062 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
1063 | { | ||
1064 | dbcon.Open(); | ||
1065 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
1066 | { | ||
1067 | cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString()); | ||
1068 | cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString()); | ||
1069 | cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString()); | ||
1070 | cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString()); | ||
1071 | |||
1072 | cmd.ExecuteNonQuery(); | ||
1073 | } | ||
1074 | } | ||
1075 | } | ||
1076 | catch (Exception e) | ||
1077 | { | ||
1078 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
1079 | ": SetUserData exception {0}", e.Message); | ||
1080 | return false; | ||
1081 | } | ||
1082 | return true; | ||
1083 | } | ||
1084 | #endregion Integration | ||
1085 | } | ||
1086 | } \ 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..af7e876 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs | |||
@@ -0,0 +1,503 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.IO; | ||
32 | using System.IO.Compression; | ||
33 | using System.Reflection; | ||
34 | using System.Security.Cryptography; | ||
35 | using System.Text; | ||
36 | using log4net; | ||
37 | using MySql.Data.MySqlClient; | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Data; | ||
41 | |||
42 | namespace 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 | } | ||
101 | } | ||
102 | |||
103 | public void Initialise() | ||
104 | { | ||
105 | throw new NotImplementedException(); | ||
106 | } | ||
107 | |||
108 | public void Dispose() { } | ||
109 | |||
110 | /// <summary> | ||
111 | /// The name of this DB provider | ||
112 | /// </summary> | ||
113 | public string Name | ||
114 | { | ||
115 | get { return "MySQL XAsset storage engine"; } | ||
116 | } | ||
117 | |||
118 | #endregion | ||
119 | |||
120 | #region IAssetDataPlugin Members | ||
121 | |||
122 | /// <summary> | ||
123 | /// Fetch Asset <paramref name="assetID"/> from database | ||
124 | /// </summary> | ||
125 | /// <param name="assetID">Asset UUID to fetch</param> | ||
126 | /// <returns>Return the asset</returns> | ||
127 | /// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks> | ||
128 | public AssetBase GetAsset(UUID assetID) | ||
129 | { | ||
130 | // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); | ||
131 | |||
132 | AssetBase asset = null; | ||
133 | |||
134 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
135 | { | ||
136 | dbcon.Open(); | ||
137 | |||
138 | using (MySqlCommand cmd = new MySqlCommand( | ||
139 | "SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID", | ||
140 | dbcon)) | ||
141 | { | ||
142 | cmd.Parameters.AddWithValue("?ID", assetID.ToString()); | ||
143 | |||
144 | try | ||
145 | { | ||
146 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
147 | { | ||
148 | if (dbReader.Read()) | ||
149 | { | ||
150 | asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString()); | ||
151 | asset.Data = (byte[])dbReader["Data"]; | ||
152 | asset.Description = (string)dbReader["Description"]; | ||
153 | |||
154 | string local = dbReader["Local"].ToString(); | ||
155 | if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) | ||
156 | asset.Local = true; | ||
157 | else | ||
158 | asset.Local = false; | ||
159 | |||
160 | asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]); | ||
161 | asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); | ||
162 | |||
163 | if (m_enableCompression) | ||
164 | { | ||
165 | using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) | ||
166 | { | ||
167 | MemoryStream outputStream = new MemoryStream(); | ||
168 | WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); | ||
169 | // int compressedLength = asset.Data.Length; | ||
170 | asset.Data = outputStream.ToArray(); | ||
171 | |||
172 | // m_log.DebugFormat( | ||
173 | // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", | ||
174 | // asset.ID, asset.Name, asset.Data.Length, compressedLength); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | catch (Exception e) | ||
183 | { | ||
184 | m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e); | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | |||
189 | return asset; | ||
190 | } | ||
191 | |||
192 | /// <summary> | ||
193 | /// Create an asset in database, or update it if existing. | ||
194 | /// </summary> | ||
195 | /// <param name="asset">Asset UUID to create</param> | ||
196 | /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> | ||
197 | public void StoreAsset(AssetBase asset) | ||
198 | { | ||
199 | // m_log.DebugFormat("[XASSETS DB]: Storing asset {0} {1}", asset.Name, asset.ID); | ||
200 | |||
201 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
202 | { | ||
203 | dbcon.Open(); | ||
204 | |||
205 | using (MySqlTransaction transaction = dbcon.BeginTransaction()) | ||
206 | { | ||
207 | string assetName = asset.Name; | ||
208 | if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) | ||
209 | { | ||
210 | assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); | ||
211 | m_log.WarnFormat( | ||
212 | "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
213 | asset.Name, asset.ID, asset.Name.Length, assetName.Length); | ||
214 | } | ||
215 | |||
216 | string assetDescription = asset.Description; | ||
217 | if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) | ||
218 | { | ||
219 | assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); | ||
220 | m_log.WarnFormat( | ||
221 | "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
222 | asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); | ||
223 | } | ||
224 | |||
225 | if (m_enableCompression) | ||
226 | { | ||
227 | MemoryStream outputStream = new MemoryStream(); | ||
228 | |||
229 | using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false)) | ||
230 | { | ||
231 | // Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue)); | ||
232 | // We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream. | ||
233 | compressionStream.Close(); | ||
234 | byte[] compressedData = outputStream.ToArray(); | ||
235 | asset.Data = compressedData; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | byte[] hash = hasher.ComputeHash(asset.Data); | ||
240 | |||
241 | // m_log.DebugFormat( | ||
242 | // "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}", | ||
243 | // asset.ID, asset.Name, hash, compressedData.Length); | ||
244 | |||
245 | try | ||
246 | { | ||
247 | using (MySqlCommand cmd = | ||
248 | new MySqlCommand( | ||
249 | "replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" + | ||
250 | "VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)", | ||
251 | dbcon)) | ||
252 | { | ||
253 | // create unix epoch time | ||
254 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
255 | cmd.Parameters.AddWithValue("?ID", asset.ID); | ||
256 | cmd.Parameters.AddWithValue("?Hash", hash); | ||
257 | cmd.Parameters.AddWithValue("?Name", assetName); | ||
258 | cmd.Parameters.AddWithValue("?Description", assetDescription); | ||
259 | cmd.Parameters.AddWithValue("?AssetType", asset.Type); | ||
260 | cmd.Parameters.AddWithValue("?Local", asset.Local); | ||
261 | cmd.Parameters.AddWithValue("?Temporary", asset.Temporary); | ||
262 | cmd.Parameters.AddWithValue("?CreateTime", now); | ||
263 | cmd.Parameters.AddWithValue("?AccessTime", now); | ||
264 | cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); | ||
265 | cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags); | ||
266 | cmd.ExecuteNonQuery(); | ||
267 | } | ||
268 | } | ||
269 | catch (Exception e) | ||
270 | { | ||
271 | m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}", | ||
272 | asset.FullID, asset.Name, e.Message); | ||
273 | |||
274 | transaction.Rollback(); | ||
275 | |||
276 | return; | ||
277 | } | ||
278 | |||
279 | if (!ExistsData(dbcon, transaction, hash)) | ||
280 | { | ||
281 | try | ||
282 | { | ||
283 | using (MySqlCommand cmd = | ||
284 | new MySqlCommand( | ||
285 | "INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)", | ||
286 | dbcon)) | ||
287 | { | ||
288 | cmd.Parameters.AddWithValue("?Hash", hash); | ||
289 | cmd.Parameters.AddWithValue("?Data", asset.Data); | ||
290 | cmd.ExecuteNonQuery(); | ||
291 | } | ||
292 | } | ||
293 | catch (Exception e) | ||
294 | { | ||
295 | m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}", | ||
296 | asset.FullID, asset.Name, e.Message); | ||
297 | |||
298 | transaction.Rollback(); | ||
299 | |||
300 | return; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | transaction.Commit(); | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
309 | /// <summary> | ||
310 | /// Updates the access time of the asset if it was accessed above a given threshhold amount of time. | ||
311 | /// </summary> | ||
312 | /// <remarks> | ||
313 | /// This gives us some insight into assets which haven't ben accessed for a long period. This is only done | ||
314 | /// over the threshold time to avoid excessive database writes as assets are fetched. | ||
315 | /// </remarks> | ||
316 | /// <param name='asset'></param> | ||
317 | /// <param name='accessTime'></param> | ||
318 | private void UpdateAccessTime(AssetMetadata assetMetadata, int accessTime) | ||
319 | { | ||
320 | DateTime now = DateTime.UtcNow; | ||
321 | |||
322 | if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates) | ||
323 | return; | ||
324 | |||
325 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
326 | { | ||
327 | dbcon.Open(); | ||
328 | MySqlCommand cmd = | ||
329 | new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon); | ||
330 | |||
331 | try | ||
332 | { | ||
333 | using (cmd) | ||
334 | { | ||
335 | // create unix epoch time | ||
336 | cmd.Parameters.AddWithValue("?ID", assetMetadata.ID); | ||
337 | cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now)); | ||
338 | cmd.ExecuteNonQuery(); | ||
339 | } | ||
340 | } | ||
341 | catch (Exception) | ||
342 | { | ||
343 | m_log.ErrorFormat( | ||
344 | "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", | ||
345 | assetMetadata.ID, assetMetadata.Name); | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /// <summary> | ||
351 | /// We assume we already have the m_dbLock. | ||
352 | /// </summary> | ||
353 | /// TODO: need to actually use the transaction. | ||
354 | /// <param name="dbcon"></param> | ||
355 | /// <param name="transaction"></param> | ||
356 | /// <param name="hash"></param> | ||
357 | /// <returns></returns> | ||
358 | private bool ExistsData(MySqlConnection dbcon, MySqlTransaction transaction, byte[] hash) | ||
359 | { | ||
360 | // m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid); | ||
361 | |||
362 | bool exists = false; | ||
363 | |||
364 | using (MySqlCommand cmd = new MySqlCommand("SELECT Hash FROM XAssetsData WHERE Hash=?Hash", dbcon)) | ||
365 | { | ||
366 | cmd.Parameters.AddWithValue("?Hash", hash); | ||
367 | |||
368 | try | ||
369 | { | ||
370 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
371 | { | ||
372 | if (dbReader.Read()) | ||
373 | { | ||
374 | // m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid); | ||
375 | exists = true; | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | catch (Exception e) | ||
380 | { | ||
381 | m_log.ErrorFormat( | ||
382 | "[XASSETS DB]: MySql failure in ExistsData fetching hash {0}. Exception {1}{2}", | ||
383 | hash, e.Message, e.StackTrace); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | return exists; | ||
388 | } | ||
389 | |||
390 | /// <summary> | ||
391 | /// Check if the assets exist in the database. | ||
392 | /// </summary> | ||
393 | /// <param name="uuids">The asset UUID's</param> | ||
394 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
395 | public bool[] AssetsExist(UUID[] uuids) | ||
396 | { | ||
397 | if (uuids.Length == 0) | ||
398 | return new bool[0]; | ||
399 | |||
400 | HashSet<UUID> exists = new HashSet<UUID>(); | ||
401 | |||
402 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
403 | string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids); | ||
404 | |||
405 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
406 | { | ||
407 | dbcon.Open(); | ||
408 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
409 | { | ||
410 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
411 | { | ||
412 | while (dbReader.Read()) | ||
413 | { | ||
414 | UUID id = DBGuid.FromDB(dbReader["ID"]); | ||
415 | exists.Add(id); | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | |||
421 | bool[] results = new bool[uuids.Length]; | ||
422 | for (int i = 0; i < uuids.Length; i++) | ||
423 | results[i] = exists.Contains(uuids[i]); | ||
424 | return results; | ||
425 | } | ||
426 | |||
427 | |||
428 | /// <summary> | ||
429 | /// Returns a list of AssetMetadata objects. The list is a subset of | ||
430 | /// the entire data set offset by <paramref name="start" /> containing | ||
431 | /// <paramref name="count" /> elements. | ||
432 | /// </summary> | ||
433 | /// <param name="start">The number of results to discard from the total data set.</param> | ||
434 | /// <param name="count">The number of rows the returned list should contain.</param> | ||
435 | /// <returns>A list of AssetMetadata objects.</returns> | ||
436 | public List<AssetMetadata> FetchAssetMetadataSet(int start, int count) | ||
437 | { | ||
438 | List<AssetMetadata> retList = new List<AssetMetadata>(count); | ||
439 | |||
440 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
441 | { | ||
442 | dbcon.Open(); | ||
443 | MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon); | ||
444 | cmd.Parameters.AddWithValue("?start", start); | ||
445 | cmd.Parameters.AddWithValue("?count", count); | ||
446 | |||
447 | try | ||
448 | { | ||
449 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
450 | { | ||
451 | while (dbReader.Read()) | ||
452 | { | ||
453 | AssetMetadata metadata = new AssetMetadata(); | ||
454 | metadata.Name = (string)dbReader["Name"]; | ||
455 | metadata.Description = (string)dbReader["Description"]; | ||
456 | metadata.Type = (sbyte)dbReader["AssetType"]; | ||
457 | metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct. | ||
458 | metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); | ||
459 | metadata.FullID = DBGuid.FromDB(dbReader["ID"]); | ||
460 | metadata.CreatorID = dbReader["CreatorID"].ToString(); | ||
461 | |||
462 | // We'll ignore this for now - it appears unused! | ||
463 | // metadata.SHA1 = dbReader["hash"]); | ||
464 | |||
465 | UpdateAccessTime(metadata, (int)dbReader["AccessTime"]); | ||
466 | |||
467 | retList.Add(metadata); | ||
468 | } | ||
469 | } | ||
470 | } | ||
471 | catch (Exception e) | ||
472 | { | ||
473 | m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | return retList; | ||
478 | } | ||
479 | |||
480 | public bool Delete(string id) | ||
481 | { | ||
482 | // m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id); | ||
483 | |||
484 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
485 | { | ||
486 | dbcon.Open(); | ||
487 | |||
488 | using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon)) | ||
489 | { | ||
490 | cmd.Parameters.AddWithValue("?ID", id); | ||
491 | cmd.ExecuteNonQuery(); | ||
492 | } | ||
493 | |||
494 | // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we | ||
495 | // keep a reference count (?) | ||
496 | } | ||
497 | |||
498 | return true; | ||
499 | } | ||
500 | |||
501 | #endregion | ||
502 | } | ||
503 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs new file mode 100644 index 0000000..c74033e --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Linq; | ||
32 | using System.Reflection; | ||
33 | using log4net; | ||
34 | using MySql.Data.MySqlClient; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | |||
38 | namespace 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.Parameters.AddWithValue("?uuid", principalID.ToString()); | ||
199 | cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); | ||
200 | |||
201 | return DoQuery(cmd); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | public int GetAssetPermissions(UUID principalID, UUID assetID) | ||
206 | { | ||
207 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
208 | { | ||
209 | dbcon.Open(); | ||
210 | |||
211 | using (MySqlCommand cmd = new MySqlCommand()) | ||
212 | { | ||
213 | cmd.Connection = dbcon; | ||
214 | |||
215 | cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); | ||
216 | cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); | ||
217 | cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); | ||
218 | |||
219 | using (IDataReader reader = cmd.ExecuteReader()) | ||
220 | { | ||
221 | |||
222 | int perms = 0; | ||
223 | |||
224 | if (reader.Read()) | ||
225 | { | ||
226 | perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); | ||
227 | } | ||
228 | |||
229 | return perms; | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | |||
235 | public override bool Store(XInventoryItem item) | ||
236 | { | ||
237 | if (!base.Store(item)) | ||
238 | return false; | ||
239 | |||
240 | IncrementFolderVersion(item.parentFolderID); | ||
241 | |||
242 | return true; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | public class MySqlFolderHandler : MySqlInventoryHandler<XInventoryFolder> | ||
247 | { | ||
248 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
249 | |||
250 | public MySqlFolderHandler(string c, string t, string m) : | ||
251 | base(c, t, m) | ||
252 | { | ||
253 | } | ||
254 | |||
255 | public bool MoveFolder(string id, string newParentFolderID) | ||
256 | { | ||
257 | XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); | ||
258 | |||
259 | if (folders.Length == 0) | ||
260 | return false; | ||
261 | |||
262 | UUID oldParentFolderUUID = folders[0].parentFolderID; | ||
263 | |||
264 | using (MySqlCommand cmd = new MySqlCommand()) | ||
265 | { | ||
266 | cmd.CommandText | ||
267 | = String.Format( | ||
268 | "update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm); | ||
269 | cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID); | ||
270 | cmd.Parameters.AddWithValue("?folderID", id); | ||
271 | |||
272 | if (ExecuteNonQuery(cmd) == 0) | ||
273 | return false; | ||
274 | } | ||
275 | |||
276 | IncrementFolderVersion(oldParentFolderUUID); | ||
277 | IncrementFolderVersion(newParentFolderID); | ||
278 | |||
279 | return true; | ||
280 | } | ||
281 | |||
282 | public override bool Store(XInventoryFolder folder) | ||
283 | { | ||
284 | if (!base.Store(folder)) | ||
285 | return false; | ||
286 | |||
287 | IncrementFolderVersion(folder.parentFolderID); | ||
288 | |||
289 | return true; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | public class MySqlInventoryHandler<T> : MySQLGenericTableHandler<T> where T: class, new() | ||
294 | { | ||
295 | public MySqlInventoryHandler(string c, string t, string m) : base(c, t, m) {} | ||
296 | |||
297 | protected bool IncrementFolderVersion(UUID folderID) | ||
298 | { | ||
299 | return IncrementFolderVersion(folderID.ToString()); | ||
300 | } | ||
301 | |||
302 | protected bool IncrementFolderVersion(string folderID) | ||
303 | { | ||
304 | // m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID); | ||
305 | // Util.PrintCallStack(); | ||
306 | |||
307 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
308 | { | ||
309 | dbcon.Open(); | ||
310 | |||
311 | using (MySqlCommand cmd = new MySqlCommand()) | ||
312 | { | ||
313 | cmd.Connection = dbcon; | ||
314 | |||
315 | cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID"); | ||
316 | cmd.Parameters.AddWithValue("?folderID", folderID); | ||
317 | |||
318 | try | ||
319 | { | ||
320 | cmd.ExecuteNonQuery(); | ||
321 | } | ||
322 | catch (Exception) | ||
323 | { | ||
324 | return false; | ||
325 | } | ||
326 | cmd.Dispose(); | ||
327 | } | ||
328 | |||
329 | dbcon.Close(); | ||
330 | } | ||
331 | |||
332 | return true; | ||
333 | } | ||
334 | } | ||
335 | } \ 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..b46d175 --- /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 | |||
28 | using System.Reflection; | ||
29 | using 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("0.8.2.*")] | ||
65 | |||
diff --git a/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations new file mode 100644 index 0000000..e496f72 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | :VERSION 1 # ------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `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=InnoDB DEFAULT CHARSET=utf8; | ||
17 | |||
18 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/AssetStore.migrations b/OpenSim/Data/MySQL/Resources/AssetStore.migrations new file mode 100644 index 0000000..661d825 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/AssetStore.migrations | |||
@@ -0,0 +1,81 @@ | |||
1 | # ----------------- | ||
2 | :VERSION 1 | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE `assets` ( | ||
7 | `id` binary(16) NOT NULL, | ||
8 | `name` varchar(64) NOT NULL, | ||
9 | `description` varchar(64) NOT NULL, | ||
10 | `assetType` tinyint(4) NOT NULL, | ||
11 | `invType` tinyint(4) NOT NULL, | ||
12 | `local` tinyint(1) NOT NULL, | ||
13 | `temporary` tinyint(1) NOT NULL, | ||
14 | `data` longblob NOT NULL, | ||
15 | PRIMARY KEY (`id`) | ||
16 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1'; | ||
17 | |||
18 | COMMIT; | ||
19 | |||
20 | # ----------------- | ||
21 | :VERSION 2 | ||
22 | |||
23 | BEGIN; | ||
24 | |||
25 | ALTER TABLE assets change id oldid binary(16); | ||
26 | ALTER TABLE assets add id varchar(36) not null default ''; | ||
27 | UPDATE assets set id = concat(substr(hex(oldid),1,8),"-",substr(hex(oldid),9,4),"-",substr(hex(oldid),13,4),"-",substr(hex(oldid),17,4),"-",substr(hex(oldid),21,12)); | ||
28 | ALTER TABLE assets drop oldid; | ||
29 | ALTER TABLE assets add constraint primary key(id); | ||
30 | |||
31 | COMMIT; | ||
32 | |||
33 | # ----------------- | ||
34 | :VERSION 3 | ||
35 | |||
36 | BEGIN; | ||
37 | |||
38 | ALTER TABLE assets change id oldid varchar(36); | ||
39 | ALTER TABLE assets add id char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
40 | UPDATE assets set id = oldid; | ||
41 | ALTER TABLE assets drop oldid; | ||
42 | ALTER TABLE assets add constraint primary key(id); | ||
43 | |||
44 | COMMIT; | ||
45 | |||
46 | # ----------------- | ||
47 | :VERSION 4 | ||
48 | |||
49 | BEGIN; | ||
50 | |||
51 | ALTER TABLE assets drop InvType; | ||
52 | |||
53 | COMMIT; | ||
54 | |||
55 | # ----------------- | ||
56 | :VERSION 5 | ||
57 | |||
58 | BEGIN; | ||
59 | |||
60 | ALTER TABLE assets add create_time integer default 0; | ||
61 | ALTER TABLE assets add access_time integer default 0; | ||
62 | |||
63 | COMMIT; | ||
64 | |||
65 | # ----------------- | ||
66 | :VERSION 6 | ||
67 | |||
68 | DELETE FROM assets WHERE id = 'dc4b9f0b-d008-45c6-96a4-01dd947ac621' | ||
69 | |||
70 | :VERSION 7 | ||
71 | |||
72 | ALTER TABLE assets ADD COLUMN asset_flags INTEGER NOT NULL DEFAULT 0; | ||
73 | |||
74 | :VERSION 8 | ||
75 | |||
76 | ALTER TABLE assets ADD COLUMN CreatorID varchar(128) NOT NULL DEFAULT ''; | ||
77 | |||
78 | :VERSION 9 | ||
79 | |||
80 | BEGIN; | ||
81 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/AuthStore.migrations b/OpenSim/Data/MySQL/Resources/AuthStore.migrations new file mode 100644 index 0000000..023c786 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/AuthStore.migrations | |||
@@ -0,0 +1,39 @@ | |||
1 | :VERSION 1 # ------------------------------- | ||
2 | |||
3 | begin; | ||
4 | |||
5 | CREATE TABLE `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 | PRIMARY KEY (`UUID`) | ||
11 | ) ENGINE=InnoDB; | ||
12 | |||
13 | CREATE TABLE `tokens` ( | ||
14 | `UUID` char(36) NOT NULL, | ||
15 | `token` varchar(255) NOT NULL, | ||
16 | `validity` datetime NOT NULL, | ||
17 | UNIQUE KEY `uuid_token` (`UUID`,`token`), | ||
18 | KEY `UUID` (`UUID`), | ||
19 | KEY `token` (`token`), | ||
20 | KEY `validity` (`validity`) | ||
21 | ) ENGINE=InnoDB; | ||
22 | |||
23 | commit; | ||
24 | |||
25 | :VERSION 2 # ------------------------------- | ||
26 | |||
27 | BEGIN; | ||
28 | |||
29 | INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users; | ||
30 | |||
31 | COMMIT; | ||
32 | |||
33 | :VERSION 3 # ------------------------------- | ||
34 | |||
35 | BEGIN; | ||
36 | |||
37 | ALTER TABLE `auth` ADD COLUMN `accountType` VARCHAR(32) NOT NULL DEFAULT 'UserAccount'; | ||
38 | |||
39 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/Avatar.migrations b/OpenSim/Data/MySQL/Resources/Avatar.migrations new file mode 100644 index 0000000..f7cf176 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/Avatar.migrations | |||
@@ -0,0 +1,20 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE Avatars ( | ||
6 | PrincipalID CHAR(36) NOT NULL, | ||
7 | Name VARCHAR(32) NOT NULL, | ||
8 | Value VARCHAR(255) NOT NULL DEFAULT '', | ||
9 | PRIMARY KEY(PrincipalID, Name), | ||
10 | KEY(PrincipalID)); | ||
11 | |||
12 | COMMIT; | ||
13 | |||
14 | :VERSION 2 | ||
15 | |||
16 | BEGIN; | ||
17 | |||
18 | alter table Avatars change column Value Value text; | ||
19 | |||
20 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/EstateStore.migrations b/OpenSim/Data/MySQL/Resources/EstateStore.migrations new file mode 100644 index 0000000..2d1c2b5 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/EstateStore.migrations | |||
@@ -0,0 +1,87 @@ | |||
1 | :VERSION 13 | ||
2 | |||
3 | # The estate migrations used to be in Region store | ||
4 | # here they will do nothing (bad) if the tables are already there, | ||
5 | # just update the store version. | ||
6 | |||
7 | BEGIN; | ||
8 | |||
9 | CREATE TABLE IF NOT EXISTS `estate_managers` ( | ||
10 | `EstateID` int(10) unsigned NOT NULL, | ||
11 | `uuid` char(36) NOT NULL, | ||
12 | KEY `EstateID` (`EstateID`) | ||
13 | ) ENGINE=InnoDB; | ||
14 | |||
15 | CREATE TABLE IF NOT EXISTS `estate_groups` ( | ||
16 | `EstateID` int(10) unsigned NOT NULL, | ||
17 | `uuid` char(36) NOT NULL, | ||
18 | KEY `EstateID` (`EstateID`) | ||
19 | ) ENGINE=InnoDB; | ||
20 | |||
21 | CREATE TABLE IF NOT EXISTS `estate_users` ( | ||
22 | `EstateID` int(10) unsigned NOT NULL, | ||
23 | `uuid` char(36) NOT NULL, | ||
24 | KEY `EstateID` (`EstateID`) | ||
25 | ) ENGINE=InnoDB; | ||
26 | |||
27 | CREATE TABLE IF NOT EXISTS `estateban` ( | ||
28 | `EstateID` int(10) unsigned NOT NULL, | ||
29 | `bannedUUID` varchar(36) NOT NULL, | ||
30 | `bannedIp` varchar(16) NOT NULL, | ||
31 | `bannedIpHostMask` varchar(16) NOT NULL, | ||
32 | `bannedNameMask` varchar(64) default NULL, | ||
33 | KEY `estateban_EstateID` (`EstateID`) | ||
34 | ) ENGINE=InnoDB; | ||
35 | |||
36 | CREATE TABLE IF NOT EXISTS `estate_settings` ( | ||
37 | `EstateID` int(10) unsigned NOT NULL auto_increment, | ||
38 | `EstateName` varchar(64) default NULL, | ||
39 | `AbuseEmailToEstateOwner` tinyint(4) NOT NULL, | ||
40 | `DenyAnonymous` tinyint(4) NOT NULL, | ||
41 | `ResetHomeOnTeleport` tinyint(4) NOT NULL, | ||
42 | `FixedSun` tinyint(4) NOT NULL, | ||
43 | `DenyTransacted` tinyint(4) NOT NULL, | ||
44 | `BlockDwell` tinyint(4) NOT NULL, | ||
45 | `DenyIdentified` tinyint(4) NOT NULL, | ||
46 | `AllowVoice` tinyint(4) NOT NULL, | ||
47 | `UseGlobalTime` tinyint(4) NOT NULL, | ||
48 | `PricePerMeter` int(11) NOT NULL, | ||
49 | `TaxFree` tinyint(4) NOT NULL, | ||
50 | `AllowDirectTeleport` tinyint(4) NOT NULL, | ||
51 | `RedirectGridX` int(11) NOT NULL, | ||
52 | `RedirectGridY` int(11) NOT NULL, | ||
53 | `ParentEstateID` int(10) unsigned NOT NULL, | ||
54 | `SunPosition` double NOT NULL, | ||
55 | `EstateSkipScripts` tinyint(4) NOT NULL, | ||
56 | `BillableFactor` float NOT NULL, | ||
57 | `PublicAccess` tinyint(4) NOT NULL, | ||
58 | `AbuseEmail` varchar(255) not null, | ||
59 | `EstateOwner` varchar(36) not null, | ||
60 | `DenyMinors` tinyint not null, | ||
61 | |||
62 | PRIMARY KEY (`EstateID`) | ||
63 | ) ENGINE=InnoDB AUTO_INCREMENT=100; | ||
64 | |||
65 | CREATE TABLE IF NOT EXISTS `estate_map` ( | ||
66 | `RegionID` char(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
67 | `EstateID` int(11) NOT NULL, | ||
68 | PRIMARY KEY (`RegionID`), | ||
69 | KEY `EstateID` (`EstateID`) | ||
70 | ) ENGINE=InnoDB; | ||
71 | |||
72 | COMMIT; | ||
73 | |||
74 | :VERSION 32 #--------------------- (moved from RegionStore migr, just in case) | ||
75 | |||
76 | BEGIN; | ||
77 | ALTER TABLE estate_settings AUTO_INCREMENT = 100; | ||
78 | COMMIT; | ||
79 | |||
80 | :VERSION 33 #--------------------- | ||
81 | |||
82 | BEGIN; | ||
83 | ALTER TABLE estate_settings ADD COLUMN `AllowLandmark` tinyint(4) NOT NULL default '1'; | ||
84 | ALTER TABLE estate_settings ADD COLUMN `AllowParcelChanges` tinyint(4) NOT NULL default '1'; | ||
85 | ALTER TABLE estate_settings ADD COLUMN `AllowSetHome` tinyint(4) NOT NULL default '1'; | ||
86 | COMMIT; | ||
87 | |||
diff --git a/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations new file mode 100644 index 0000000..87d08c6 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | # ----------------- | ||
2 | :VERSION 1 | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE `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=InnoDB DEFAULT CHARSET=utf8; | ||
17 | |||
18 | COMMIT; \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations new file mode 100644 index 0000000..5faf956 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations | |||
@@ -0,0 +1,32 @@ | |||
1 | :VERSION 1 # ------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `Friends` ( | ||
6 | `PrincipalID` CHAR(36) NOT NULL, | ||
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`, `Friend`), | ||
11 | KEY(`PrincipalID`) | ||
12 | ) ENGINE=InnoDB; | ||
13 | |||
14 | COMMIT; | ||
15 | |||
16 | :VERSION 2 # ------------------------- | ||
17 | |||
18 | BEGIN; | ||
19 | |||
20 | INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`; | ||
21 | |||
22 | COMMIT; | ||
23 | |||
24 | :VERSION 3 # ------------------------- | ||
25 | |||
26 | BEGIN; | ||
27 | |||
28 | ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; | ||
29 | ALTER TABLE `Friends` DROP PRIMARY KEY; | ||
30 | ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36)); | ||
31 | |||
32 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/GridStore.migrations b/OpenSim/Data/MySQL/Resources/GridStore.migrations new file mode 100644 index 0000000..98ba8c5 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/GridStore.migrations | |||
@@ -0,0 +1,105 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | CREATE TABLE `regions` ( | ||
4 | `uuid` varchar(36) NOT NULL, | ||
5 | `regionHandle` bigint(20) unsigned NOT NULL, | ||
6 | `regionName` varchar(32) default NULL, | ||
7 | `regionRecvKey` varchar(128) default NULL, | ||
8 | `regionSendKey` varchar(128) default NULL, | ||
9 | `regionSecret` varchar(128) default NULL, | ||
10 | `regionDataURI` varchar(255) default NULL, | ||
11 | `serverIP` varchar(64) default NULL, | ||
12 | `serverPort` int(10) unsigned default NULL, | ||
13 | `serverURI` varchar(255) default NULL, | ||
14 | `locX` int(10) unsigned default NULL, | ||
15 | `locY` int(10) unsigned default NULL, | ||
16 | `locZ` int(10) unsigned default NULL, | ||
17 | `eastOverrideHandle` bigint(20) unsigned default NULL, | ||
18 | `westOverrideHandle` bigint(20) unsigned default NULL, | ||
19 | `southOverrideHandle` bigint(20) unsigned default NULL, | ||
20 | `northOverrideHandle` bigint(20) unsigned default NULL, | ||
21 | `regionAssetURI` varchar(255) default NULL, | ||
22 | `regionAssetRecvKey` varchar(128) default NULL, | ||
23 | `regionAssetSendKey` varchar(128) default NULL, | ||
24 | `regionUserURI` varchar(255) default NULL, | ||
25 | `regionUserRecvKey` varchar(128) default NULL, | ||
26 | `regionUserSendKey` varchar(128) default NULL, `regionMapTexture` varchar(36) default NULL, | ||
27 | `serverHttpPort` int(10) default NULL, `serverRemotingPort` int(10) default NULL, | ||
28 | `owner_uuid` varchar(36) default '00000000-0000-0000-0000-000000000000' not null, | ||
29 | `originUUID` varchar(36), | ||
30 | PRIMARY KEY (`uuid`), | ||
31 | KEY `regionName` (`regionName`), | ||
32 | KEY `regionHandle` (`regionHandle`), | ||
33 | KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`) | ||
34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Rev. 3'; | ||
35 | |||
36 | :VERSION 2 | ||
37 | |||
38 | BEGIN; | ||
39 | |||
40 | ALTER TABLE regions add column access integer unsigned default 1; | ||
41 | |||
42 | COMMIT; | ||
43 | |||
44 | :VERSION 3 | ||
45 | |||
46 | BEGIN; | ||
47 | |||
48 | ALTER TABLE regions add column ScopeID char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
49 | |||
50 | create index ScopeID on regions(ScopeID); | ||
51 | |||
52 | COMMIT; | ||
53 | |||
54 | :VERSION 4 | ||
55 | |||
56 | BEGIN; | ||
57 | |||
58 | ALTER TABLE regions add column sizeX integer not null default 0; | ||
59 | ALTER TABLE regions add column sizeY integer not null default 0; | ||
60 | |||
61 | COMMIT; | ||
62 | |||
63 | :VERSION 5 | ||
64 | |||
65 | BEGIN; | ||
66 | |||
67 | ALTER TABLE `regions` ADD COLUMN `flags` integer NOT NULL DEFAULT 0; | ||
68 | CREATE INDEX flags ON regions(flags); | ||
69 | |||
70 | COMMIT; | ||
71 | |||
72 | :VERSION 6 | ||
73 | |||
74 | BEGIN; | ||
75 | |||
76 | ALTER TABLE `regions` ADD COLUMN `last_seen` integer NOT NULL DEFAULT 0; | ||
77 | |||
78 | COMMIT; | ||
79 | |||
80 | :VERSION 7 | ||
81 | |||
82 | BEGIN; | ||
83 | |||
84 | ALTER TABLE `regions` ADD COLUMN `PrincipalID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; | ||
85 | ALTER TABLE `regions` ADD COLUMN `Token` varchar(255) NOT NULL; | ||
86 | |||
87 | COMMIT; | ||
88 | |||
89 | |||
90 | :VERSION 8 # ------------ | ||
91 | |||
92 | BEGIN; | ||
93 | |||
94 | alter table regions modify column regionName varchar(128) default NULL; | ||
95 | |||
96 | COMMIT; | ||
97 | |||
98 | :VERSION 9 # ------------ | ||
99 | |||
100 | BEGIN; | ||
101 | |||
102 | alter table regions add column `parcelMapTexture` varchar(36) default NULL; | ||
103 | |||
104 | COMMIT; | ||
105 | |||
diff --git a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations new file mode 100644 index 0000000..d08e096 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations | |||
@@ -0,0 +1,24 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `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=InnoDB; | ||
18 | |||
19 | COMMIT; | ||
20 | |||
21 | :VERSION 2 # -------------------------- | ||
22 | BEGIN; | ||
23 | |||
24 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations new file mode 100644 index 0000000..b4e4422 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `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=InnoDB; | ||
16 | |||
17 | COMMIT; | ||
18 | |||
diff --git a/OpenSim/Data/MySQL/Resources/IM_Store.migrations b/OpenSim/Data/MySQL/Resources/IM_Store.migrations new file mode 100644 index 0000000..79ead98 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/IM_Store.migrations | |||
@@ -0,0 +1,42 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `im_offline` ( | ||
6 | `ID` MEDIUMINT NOT NULL AUTO_INCREMENT, | ||
7 | `PrincipalID` char(36) NOT NULL default '', | ||
8 | `Message` text NOT NULL, | ||
9 | `TMStamp` timestamp NOT NULL, | ||
10 | PRIMARY KEY (`ID`), | ||
11 | KEY `PrincipalID` (`PrincipalID`) | ||
12 | ) ENGINE=MyISAM; | ||
13 | |||
14 | COMMIT; | ||
15 | |||
16 | :VERSION 2 # -------------------------- | ||
17 | |||
18 | BEGIN; | ||
19 | |||
20 | INSERT INTO `im_offline` SELECT * from `diva_im_offline`; | ||
21 | DROP TABLE `diva_im_offline`; | ||
22 | DELETE FROM `migrations` WHERE name='diva_im_Store'; | ||
23 | |||
24 | COMMIT; | ||
25 | |||
26 | :VERSION 3 # -------------------------- | ||
27 | |||
28 | BEGIN; | ||
29 | |||
30 | ALTER TABLE `im_offline` | ||
31 | ADD `FromID` char(36) NOT NULL default '' AFTER `PrincipalID`, | ||
32 | ADD KEY `FromID` (`FromID`); | ||
33 | |||
34 | COMMIT; | ||
35 | |||
36 | :VERSION 4 # -------------------------- | ||
37 | |||
38 | BEGIN; | ||
39 | |||
40 | ALTER TABLE im_offline CONVERT TO CHARACTER SET utf8; | ||
41 | |||
42 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/InventoryStore.migrations b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations new file mode 100644 index 0000000..993a5a0 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations | |||
@@ -0,0 +1,109 @@ | |||
1 | :VERSION 1 # ------------ | ||
2 | BEGIN; | ||
3 | |||
4 | CREATE TABLE `inventoryfolders` ( | ||
5 | `folderID` varchar(36) NOT NULL default '', | ||
6 | `agentID` varchar(36) default NULL, | ||
7 | `parentFolderID` varchar(36) default NULL, | ||
8 | `folderName` varchar(64) default NULL, | ||
9 | `type` smallint NOT NULL default 0, | ||
10 | `version` int NOT NULL default 0, | ||
11 | PRIMARY KEY (`folderID`), | ||
12 | KEY `owner` (`agentID`), | ||
13 | KEY `parent` (`parentFolderID`) | ||
14 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
15 | |||
16 | CREATE TABLE `inventoryitems` ( | ||
17 | `inventoryID` varchar(36) NOT NULL default '', | ||
18 | `assetID` varchar(36) default NULL, | ||
19 | `assetType` int(11) default NULL, | ||
20 | `parentFolderID` varchar(36) default NULL, | ||
21 | `avatarID` varchar(36) default NULL, | ||
22 | `inventoryName` varchar(64) default NULL, | ||
23 | `inventoryDescription` varchar(128) default NULL, | ||
24 | `inventoryNextPermissions` int(10) unsigned default NULL, | ||
25 | `inventoryCurrentPermissions` int(10) unsigned default NULL, | ||
26 | `invType` int(11) default NULL, | ||
27 | `creatorID` varchar(36) default NULL, | ||
28 | `inventoryBasePermissions` int(10) unsigned NOT NULL default 0, | ||
29 | `inventoryEveryOnePermissions` int(10) unsigned NOT NULL default 0, | ||
30 | `salePrice` int(11) NOT NULL default 0, | ||
31 | `saleType` tinyint(4) NOT NULL default 0, | ||
32 | `creationDate` int(11) NOT NULL default 0, | ||
33 | `groupID` varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
34 | `groupOwned` tinyint(4) NOT NULL default 0, | ||
35 | `flags` int(11) unsigned NOT NULL default 0, | ||
36 | PRIMARY KEY (`inventoryID`), | ||
37 | KEY `owner` (`avatarID`), | ||
38 | KEY `folder` (`parentFolderID`) | ||
39 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
40 | |||
41 | COMMIT; | ||
42 | |||
43 | :VERSION 2 # ------------ | ||
44 | |||
45 | BEGIN; | ||
46 | |||
47 | ALTER TABLE inventoryfolders change folderID folderIDold varchar(36); | ||
48 | ALTER TABLE inventoryfolders change agentID agentIDold varchar(36); | ||
49 | ALTER TABLE inventoryfolders change parentFolderID parentFolderIDold varchar(36); | ||
50 | ALTER TABLE inventoryfolders add folderID char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
51 | ALTER TABLE inventoryfolders add agentID char(36) default NULL; | ||
52 | ALTER TABLE inventoryfolders add parentFolderID char(36) default NULL; | ||
53 | UPDATE inventoryfolders set folderID = folderIDold, agentID = agentIDold, parentFolderID = parentFolderIDold; | ||
54 | ALTER TABLE inventoryfolders drop folderIDold; | ||
55 | ALTER TABLE inventoryfolders drop agentIDold; | ||
56 | ALTER TABLE inventoryfolders drop parentFolderIDold; | ||
57 | ALTER TABLE inventoryfolders add constraint primary key(folderID); | ||
58 | ALTER TABLE inventoryfolders add index inventoryfolders_agentid(agentID); | ||
59 | ALTER TABLE inventoryfolders add index inventoryfolders_parentFolderid(parentFolderID); | ||
60 | |||
61 | ALTER TABLE inventoryitems change inventoryID inventoryIDold varchar(36); | ||
62 | ALTER TABLE inventoryitems change avatarID avatarIDold varchar(36); | ||
63 | ALTER TABLE inventoryitems change parentFolderID parentFolderIDold varchar(36); | ||
64 | ALTER TABLE inventoryitems add inventoryID char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
65 | ALTER TABLE inventoryitems add avatarID char(36) default NULL; | ||
66 | ALTER TABLE inventoryitems add parentFolderID char(36) default NULL; | ||
67 | UPDATE inventoryitems set inventoryID = inventoryIDold, avatarID = avatarIDold, parentFolderID = parentFolderIDold; | ||
68 | ALTER TABLE inventoryitems drop inventoryIDold; | ||
69 | ALTER TABLE inventoryitems drop avatarIDold; | ||
70 | ALTER TABLE inventoryitems drop parentFolderIDold; | ||
71 | ALTER TABLE inventoryitems add constraint primary key(inventoryID); | ||
72 | ALTER TABLE inventoryitems add index inventoryitems_avatarid(avatarID); | ||
73 | ALTER TABLE inventoryitems add index inventoryitems_parentFolderid(parentFolderID); | ||
74 | |||
75 | COMMIT; | ||
76 | |||
77 | :VERSION 3 # ------------ | ||
78 | |||
79 | BEGIN; | ||
80 | |||
81 | alter table inventoryitems add column inventoryGroupPermissions integer unsigned not null default 0; | ||
82 | |||
83 | COMMIT; | ||
84 | |||
85 | :VERSION 4 # ------------ | ||
86 | |||
87 | BEGIN; | ||
88 | |||
89 | update inventoryitems set creatorID = '00000000-0000-0000-0000-000000000000' where creatorID is NULL; | ||
90 | update inventoryitems set creatorID = '00000000-0000-0000-0000-000000000000' where creatorID = ''; | ||
91 | alter table inventoryitems modify column creatorID varchar(36) not NULL default '00000000-0000-0000-0000-000000000000'; | ||
92 | |||
93 | COMMIT; | ||
94 | |||
95 | :VERSION 5 # ------------ | ||
96 | |||
97 | BEGIN; | ||
98 | |||
99 | alter table inventoryitems modify column creatorID varchar(128) not NULL default '00000000-0000-0000-0000-000000000000'; | ||
100 | |||
101 | COMMIT; | ||
102 | |||
103 | :VERSION 6 # ------------ | ||
104 | |||
105 | BEGIN; | ||
106 | |||
107 | alter table inventoryitems modify column creatorID varchar(255) not NULL default '00000000-0000-0000-0000-000000000000'; | ||
108 | |||
109 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/LogStore.migrations b/OpenSim/Data/MySQL/Resources/LogStore.migrations new file mode 100644 index 0000000..9ac26ac --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/LogStore.migrations | |||
@@ -0,0 +1,13 @@ | |||
1 | | ||
2 | :VERSION 1 | ||
3 | |||
4 | CREATE TABLE `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=InnoDB DEFAULT CHARSET=utf8; | ||
diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations new file mode 100644 index 0000000..c4e40fa --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/Presence.migrations | |||
@@ -0,0 +1,31 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `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 | ) ENGINE=InnoDB; | ||
11 | |||
12 | CREATE UNIQUE INDEX SessionID ON Presence(SessionID); | ||
13 | CREATE INDEX UserID ON Presence(UserID); | ||
14 | |||
15 | COMMIT; | ||
16 | |||
17 | :VERSION 2 # -------------------------- | ||
18 | |||
19 | BEGIN; | ||
20 | |||
21 | ALTER TABLE `Presence` ADD COLUMN LastSeen timestamp; | ||
22 | |||
23 | COMMIT; | ||
24 | |||
25 | :VERSION 3 # -------------------------- | ||
26 | |||
27 | BEGIN; | ||
28 | |||
29 | CREATE INDEX RegionID ON Presence(RegionID); | ||
30 | |||
31 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations new file mode 100644 index 0000000..ac31380 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations | |||
@@ -0,0 +1,950 @@ | |||
1 | |||
2 | :VERSION 1 #--------------------- | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE `prims` ( | ||
7 | `UUID` varchar(255) NOT NULL, | ||
8 | `RegionUUID` varchar(255) default NULL, | ||
9 | `ParentID` int(11) default NULL, | ||
10 | `CreationDate` int(11) default NULL, | ||
11 | `Name` varchar(255) default NULL, | ||
12 | `SceneGroupID` varchar(255) default NULL, | ||
13 | `Text` varchar(255) default NULL, | ||
14 | `Description` varchar(255) default NULL, | ||
15 | `SitName` varchar(255) default NULL, | ||
16 | `TouchName` varchar(255) default NULL, | ||
17 | `ObjectFlags` int(11) default NULL, | ||
18 | `CreatorID` varchar(255) default NULL, | ||
19 | `OwnerID` varchar(255) default NULL, | ||
20 | `GroupID` varchar(255) default NULL, | ||
21 | `LastOwnerID` varchar(255) default NULL, | ||
22 | `OwnerMask` int(11) default NULL, | ||
23 | `NextOwnerMask` int(11) default NULL, | ||
24 | `GroupMask` int(11) default NULL, | ||
25 | `EveryoneMask` int(11) default NULL, | ||
26 | `BaseMask` int(11) default NULL, | ||
27 | `PositionX` float default NULL, | ||
28 | `PositionY` float default NULL, | ||
29 | `PositionZ` float default NULL, | ||
30 | `GroupPositionX` float default NULL, | ||
31 | `GroupPositionY` float default NULL, | ||
32 | `GroupPositionZ` float default NULL, | ||
33 | `VelocityX` float default NULL, | ||
34 | `VelocityY` float default NULL, | ||
35 | `VelocityZ` float default NULL, | ||
36 | `AngularVelocityX` float default NULL, | ||
37 | `AngularVelocityY` float default NULL, | ||
38 | `AngularVelocityZ` float default NULL, | ||
39 | `AccelerationX` float default NULL, | ||
40 | `AccelerationY` float default NULL, | ||
41 | `AccelerationZ` float default NULL, | ||
42 | `RotationX` float default NULL, | ||
43 | `RotationY` float default NULL, | ||
44 | `RotationZ` float default NULL, | ||
45 | `RotationW` float default NULL, | ||
46 | `SitTargetOffsetX` float default NULL, | ||
47 | `SitTargetOffsetY` float default NULL, | ||
48 | `SitTargetOffsetZ` float default NULL, | ||
49 | `SitTargetOrientW` float default NULL, | ||
50 | `SitTargetOrientX` float default NULL, | ||
51 | `SitTargetOrientY` float default NULL, | ||
52 | `SitTargetOrientZ` float default NULL, | ||
53 | PRIMARY KEY (`UUID`) | ||
54 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
55 | |||
56 | CREATE TABLE `primshapes` ( | ||
57 | `UUID` varchar(255) NOT NULL, | ||
58 | `Shape` int(11) default NULL, | ||
59 | `ScaleX` float default NULL, | ||
60 | `ScaleY` float default NULL, | ||
61 | `ScaleZ` float default NULL, | ||
62 | `PCode` int(11) default NULL, | ||
63 | `PathBegin` int(11) default NULL, | ||
64 | `PathEnd` int(11) default NULL, | ||
65 | `PathScaleX` int(11) default NULL, | ||
66 | `PathScaleY` int(11) default NULL, | ||
67 | `PathShearX` int(11) default NULL, | ||
68 | `PathShearY` int(11) default NULL, | ||
69 | `PathSkew` int(11) default NULL, | ||
70 | `PathCurve` int(11) default NULL, | ||
71 | `PathRadiusOffset` int(11) default NULL, | ||
72 | `PathRevolutions` int(11) default NULL, | ||
73 | `PathTaperX` int(11) default NULL, | ||
74 | `PathTaperY` int(11) default NULL, | ||
75 | `PathTwist` int(11) default NULL, | ||
76 | `PathTwistBegin` int(11) default NULL, | ||
77 | `ProfileBegin` int(11) default NULL, | ||
78 | `ProfileEnd` int(11) default NULL, | ||
79 | `ProfileCurve` int(11) default NULL, | ||
80 | `ProfileHollow` int(11) default NULL, | ||
81 | `State` int(11) default NULL, | ||
82 | `Texture` longblob, | ||
83 | `ExtraParams` longblob, | ||
84 | PRIMARY KEY (`UUID`) | ||
85 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
86 | |||
87 | CREATE TABLE `primitems` ( | ||
88 | `itemID` varchar(255) NOT NULL, | ||
89 | `primID` varchar(255) default NULL, | ||
90 | `assetID` varchar(255) default NULL, | ||
91 | `parentFolderID` varchar(255) default NULL, | ||
92 | `invType` int(11) default NULL, | ||
93 | `assetType` int(11) default NULL, | ||
94 | `name` varchar(255) default NULL, | ||
95 | `description` varchar(255) default NULL, | ||
96 | `creationDate` bigint(20) default NULL, | ||
97 | `creatorID` varchar(255) default NULL, | ||
98 | `ownerID` varchar(255) default NULL, | ||
99 | `lastOwnerID` varchar(255) default NULL, | ||
100 | `groupID` varchar(255) default NULL, | ||
101 | `nextPermissions` int(11) default NULL, | ||
102 | `currentPermissions` int(11) default NULL, | ||
103 | `basePermissions` int(11) default NULL, | ||
104 | `everyonePermissions` int(11) default NULL, | ||
105 | `groupPermissions` int(11) default NULL, | ||
106 | PRIMARY KEY (`itemID`) | ||
107 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
108 | |||
109 | CREATE TABLE `terrain` ( | ||
110 | `RegionUUID` varchar(255) default NULL, | ||
111 | `Revision` int(11) default NULL, | ||
112 | `Heightfield` longblob | ||
113 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
114 | |||
115 | CREATE TABLE `land` ( | ||
116 | `UUID` varchar(255) NOT NULL, | ||
117 | `RegionUUID` varchar(255) default NULL, | ||
118 | `LocalLandID` int(11) default NULL, | ||
119 | `Bitmap` longblob, | ||
120 | `Name` varchar(255) default NULL, | ||
121 | `Description` varchar(255) default NULL, | ||
122 | `OwnerUUID` varchar(255) default NULL, | ||
123 | `IsGroupOwned` int(11) default NULL, | ||
124 | `Area` int(11) default NULL, | ||
125 | `AuctionID` int(11) default NULL, | ||
126 | `Category` int(11) default NULL, | ||
127 | `ClaimDate` int(11) default NULL, | ||
128 | `ClaimPrice` int(11) default NULL, | ||
129 | `GroupUUID` varchar(255) default NULL, | ||
130 | `SalePrice` int(11) default NULL, | ||
131 | `LandStatus` int(11) default NULL, | ||
132 | `LandFlags` int(11) default NULL, | ||
133 | `LandingType` int(11) default NULL, | ||
134 | `MediaAutoScale` int(11) default NULL, | ||
135 | `MediaTextureUUID` varchar(255) default NULL, | ||
136 | `MediaURL` varchar(255) default NULL, | ||
137 | `MusicURL` varchar(255) default NULL, | ||
138 | `PassHours` float default NULL, | ||
139 | `PassPrice` int(11) default NULL, | ||
140 | `SnapshotUUID` varchar(255) default NULL, | ||
141 | `UserLocationX` float default NULL, | ||
142 | `UserLocationY` float default NULL, | ||
143 | `UserLocationZ` float default NULL, | ||
144 | `UserLookAtX` float default NULL, | ||
145 | `UserLookAtY` float default NULL, | ||
146 | `UserLookAtZ` float default NULL, | ||
147 | `AuthbuyerID` varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
148 | PRIMARY KEY (`UUID`) | ||
149 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
150 | |||
151 | CREATE TABLE `landaccesslist` ( | ||
152 | `LandUUID` varchar(255) default NULL, | ||
153 | `AccessUUID` varchar(255) default NULL, | ||
154 | `Flags` int(11) default NULL | ||
155 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
156 | |||
157 | COMMIT; | ||
158 | |||
159 | :VERSION 2 #--------------------- | ||
160 | |||
161 | BEGIN; | ||
162 | |||
163 | CREATE index prims_regionuuid on prims(RegionUUID); | ||
164 | CREATE index primitems_primid on primitems(primID); | ||
165 | |||
166 | COMMIT; | ||
167 | |||
168 | :VERSION 3 #--------------------- | ||
169 | |||
170 | BEGIN; | ||
171 | CREATE TABLE regionban (regionUUID VARCHAR(36) NOT NULL, bannedUUID VARCHAR(36) NOT NULL, bannedIp VARCHAR(16) NOT NULL, bannedIpHostMask VARCHAR(16) NOT NULL) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Rev. 1'; | ||
172 | COMMIT; | ||
173 | |||
174 | :VERSION 4 #--------------------- | ||
175 | |||
176 | BEGIN; | ||
177 | |||
178 | ALTER TABLE primitems add flags integer not null default 0; | ||
179 | |||
180 | COMMIT; | ||
181 | |||
182 | :VERSION 5 #--------------------- | ||
183 | BEGIN; | ||
184 | |||
185 | create table regionsettings ( | ||
186 | regionUUID char(36) not null, | ||
187 | block_terraform integer not null, | ||
188 | block_fly integer not null, | ||
189 | allow_damage integer not null, | ||
190 | restrict_pushing integer not null, | ||
191 | allow_land_resell integer not null, | ||
192 | allow_land_join_divide integer not null, | ||
193 | block_show_in_search integer not null, | ||
194 | agent_limit integer not null, | ||
195 | object_bonus float not null, | ||
196 | maturity integer not null, | ||
197 | disable_scripts integer not null, | ||
198 | disable_collisions integer not null, | ||
199 | disable_physics integer not null, | ||
200 | terrain_texture_1 char(36) not null, | ||
201 | terrain_texture_2 char(36) not null, | ||
202 | terrain_texture_3 char(36) not null, | ||
203 | terrain_texture_4 char(36) not null, | ||
204 | elevation_1_nw float not null, | ||
205 | elevation_2_nw float not null, | ||
206 | elevation_1_ne float not null, | ||
207 | elevation_2_ne float not null, | ||
208 | elevation_1_se float not null, | ||
209 | elevation_2_se float not null, | ||
210 | elevation_1_sw float not null, | ||
211 | elevation_2_sw float not null, | ||
212 | water_height float not null, | ||
213 | terrain_raise_limit float not null, | ||
214 | terrain_lower_limit float not null, | ||
215 | use_estate_sun integer not null, | ||
216 | fixed_sun integer not null, | ||
217 | sun_position float not null, | ||
218 | covenant char(36), | ||
219 | primary key(regionUUID) | ||
220 | ); | ||
221 | |||
222 | COMMIT; | ||
223 | |||
224 | |||
225 | :VERSION 6 #--------------------- | ||
226 | |||
227 | BEGIN; | ||
228 | |||
229 | alter table landaccesslist ENGINE = InnoDB; | ||
230 | alter table migrations ENGINE = InnoDB; | ||
231 | alter table primitems ENGINE = InnoDB; | ||
232 | alter table prims ENGINE = InnoDB; | ||
233 | alter table primshapes ENGINE = InnoDB; | ||
234 | alter table regionsettings ENGINE = InnoDB; | ||
235 | alter table terrain ENGINE = InnoDB; | ||
236 | |||
237 | COMMIT; | ||
238 | |||
239 | :VERSION 7 #--------------------- | ||
240 | |||
241 | BEGIN; | ||
242 | |||
243 | ALTER TABLE prims change UUID UUIDold varchar(255); | ||
244 | ALTER TABLE prims change RegionUUID RegionUUIDold varchar(255); | ||
245 | ALTER TABLE prims change CreatorID CreatorIDold varchar(255); | ||
246 | ALTER TABLE prims change OwnerID OwnerIDold varchar(255); | ||
247 | ALTER TABLE prims change GroupID GroupIDold varchar(255); | ||
248 | ALTER TABLE prims change LastOwnerID LastOwnerIDold varchar(255); | ||
249 | ALTER TABLE prims add UUID char(36); | ||
250 | ALTER TABLE prims add RegionUUID char(36); | ||
251 | ALTER TABLE prims add CreatorID char(36); | ||
252 | ALTER TABLE prims add OwnerID char(36); | ||
253 | ALTER TABLE prims add GroupID char(36); | ||
254 | ALTER TABLE prims add LastOwnerID char(36); | ||
255 | UPDATE prims set UUID = UUIDold, RegionUUID = RegionUUIDold, CreatorID = CreatorIDold, OwnerID = OwnerIDold, GroupID = GroupIDold, LastOwnerID = LastOwnerIDold; | ||
256 | ALTER TABLE prims drop UUIDold; | ||
257 | ALTER TABLE prims drop RegionUUIDold; | ||
258 | ALTER TABLE prims drop CreatorIDold; | ||
259 | ALTER TABLE prims drop OwnerIDold; | ||
260 | ALTER TABLE prims drop GroupIDold; | ||
261 | ALTER TABLE prims drop LastOwnerIDold; | ||
262 | ALTER TABLE prims add constraint primary key(UUID); | ||
263 | ALTER TABLE prims add index prims_regionuuid(RegionUUID); | ||
264 | |||
265 | COMMIT; | ||
266 | |||
267 | :VERSION 8 #--------------------- | ||
268 | |||
269 | BEGIN; | ||
270 | |||
271 | ALTER TABLE primshapes change UUID UUIDold varchar(255); | ||
272 | ALTER TABLE primshapes add UUID char(36); | ||
273 | UPDATE primshapes set UUID = UUIDold; | ||
274 | ALTER TABLE primshapes drop UUIDold; | ||
275 | ALTER TABLE primshapes add constraint primary key(UUID); | ||
276 | |||
277 | COMMIT; | ||
278 | |||
279 | :VERSION 9 #--------------------- | ||
280 | |||
281 | BEGIN; | ||
282 | |||
283 | ALTER TABLE primitems change itemID itemIDold varchar(255); | ||
284 | ALTER TABLE primitems change primID primIDold varchar(255); | ||
285 | ALTER TABLE primitems change assetID assetIDold varchar(255); | ||
286 | ALTER TABLE primitems change parentFolderID parentFolderIDold varchar(255); | ||
287 | ALTER TABLE primitems change creatorID creatorIDold varchar(255); | ||
288 | ALTER TABLE primitems change ownerID ownerIDold varchar(255); | ||
289 | ALTER TABLE primitems change groupID groupIDold varchar(255); | ||
290 | ALTER TABLE primitems change lastOwnerID lastOwnerIDold varchar(255); | ||
291 | ALTER TABLE primitems add itemID char(36); | ||
292 | ALTER TABLE primitems add primID char(36); | ||
293 | ALTER TABLE primitems add assetID char(36); | ||
294 | ALTER TABLE primitems add parentFolderID char(36); | ||
295 | ALTER TABLE primitems add creatorID char(36); | ||
296 | ALTER TABLE primitems add ownerID char(36); | ||
297 | ALTER TABLE primitems add groupID char(36); | ||
298 | ALTER TABLE primitems add lastOwnerID char(36); | ||
299 | UPDATE primitems set itemID = itemIDold, primID = primIDold, assetID = assetIDold, parentFolderID = parentFolderIDold, creatorID = creatorIDold, ownerID = ownerIDold, groupID = groupIDold, lastOwnerID = lastOwnerIDold; | ||
300 | ALTER TABLE primitems drop itemIDold; | ||
301 | ALTER TABLE primitems drop primIDold; | ||
302 | ALTER TABLE primitems drop assetIDold; | ||
303 | ALTER TABLE primitems drop parentFolderIDold; | ||
304 | ALTER TABLE primitems drop creatorIDold; | ||
305 | ALTER TABLE primitems drop ownerIDold; | ||
306 | ALTER TABLE primitems drop groupIDold; | ||
307 | ALTER TABLE primitems drop lastOwnerIDold; | ||
308 | ALTER TABLE primitems add constraint primary key(itemID); | ||
309 | ALTER TABLE primitems add index primitems_primid(primID); | ||
310 | |||
311 | COMMIT; | ||
312 | |||
313 | :VERSION 10 #--------------------- | ||
314 | |||
315 | # 1 "010_RegionStore.sql" | ||
316 | # 1 "<built-in>" | ||
317 | # 1 "<command line>" | ||
318 | # 1 "010_RegionStore.sql" | ||
319 | BEGIN; | ||
320 | |||
321 | DELETE FROM regionsettings; | ||
322 | |||
323 | COMMIT; | ||
324 | |||
325 | |||
326 | :VERSION 11 #--------------------- | ||
327 | |||
328 | BEGIN; | ||
329 | |||
330 | ALTER TABLE prims change SceneGroupID SceneGroupIDold varchar(255); | ||
331 | ALTER TABLE prims add SceneGroupID char(36); | ||
332 | UPDATE prims set SceneGroupID = SceneGroupIDold; | ||
333 | ALTER TABLE prims drop SceneGroupIDold; | ||
334 | ALTER TABLE prims add index prims_scenegroupid(SceneGroupID); | ||
335 | |||
336 | COMMIT; | ||
337 | |||
338 | :VERSION 12 #--------------------- | ||
339 | |||
340 | BEGIN; | ||
341 | |||
342 | ALTER TABLE prims add index prims_parentid(ParentID); | ||
343 | |||
344 | COMMIT; | ||
345 | |||
346 | :VERSION 13 #--------------------- | ||
347 | begin; | ||
348 | |||
349 | drop table regionsettings; | ||
350 | |||
351 | CREATE TABLE `regionsettings` ( | ||
352 | `regionUUID` char(36) NOT NULL, | ||
353 | `block_terraform` int(11) NOT NULL, | ||
354 | `block_fly` int(11) NOT NULL, | ||
355 | `allow_damage` int(11) NOT NULL, | ||
356 | `restrict_pushing` int(11) NOT NULL, | ||
357 | `allow_land_resell` int(11) NOT NULL, | ||
358 | `allow_land_join_divide` int(11) NOT NULL, | ||
359 | `block_show_in_search` int(11) NOT NULL, | ||
360 | `agent_limit` int(11) NOT NULL, | ||
361 | `object_bonus` float NOT NULL, | ||
362 | `maturity` int(11) NOT NULL, | ||
363 | `disable_scripts` int(11) NOT NULL, | ||
364 | `disable_collisions` int(11) NOT NULL, | ||
365 | `disable_physics` int(11) NOT NULL, | ||
366 | `terrain_texture_1` char(36) NOT NULL, | ||
367 | `terrain_texture_2` char(36) NOT NULL, | ||
368 | `terrain_texture_3` char(36) NOT NULL, | ||
369 | `terrain_texture_4` char(36) NOT NULL, | ||
370 | `elevation_1_nw` float NOT NULL, | ||
371 | `elevation_2_nw` float NOT NULL, | ||
372 | `elevation_1_ne` float NOT NULL, | ||
373 | `elevation_2_ne` float NOT NULL, | ||
374 | `elevation_1_se` float NOT NULL, | ||
375 | `elevation_2_se` float NOT NULL, | ||
376 | `elevation_1_sw` float NOT NULL, | ||
377 | `elevation_2_sw` float NOT NULL, | ||
378 | `water_height` float NOT NULL, | ||
379 | `terrain_raise_limit` float NOT NULL, | ||
380 | `terrain_lower_limit` float NOT NULL, | ||
381 | `use_estate_sun` int(11) NOT NULL, | ||
382 | `fixed_sun` int(11) NOT NULL, | ||
383 | `sun_position` float NOT NULL, | ||
384 | `covenant` char(36) default NULL, | ||
385 | `Sandbox` tinyint(4) NOT NULL, | ||
386 | PRIMARY KEY (`regionUUID`) | ||
387 | ) ENGINE=InnoDB; | ||
388 | |||
389 | commit; | ||
390 | |||
391 | :VERSION 16 #--------------------- | ||
392 | |||
393 | BEGIN; | ||
394 | |||
395 | ALTER TABLE prims ADD COLUMN PayPrice integer not null default 0; | ||
396 | ALTER TABLE prims ADD COLUMN PayButton1 integer not null default 0; | ||
397 | ALTER TABLE prims ADD COLUMN PayButton2 integer not null default 0; | ||
398 | ALTER TABLE prims ADD COLUMN PayButton3 integer not null default 0; | ||
399 | ALTER TABLE prims ADD COLUMN PayButton4 integer not null default 0; | ||
400 | ALTER TABLE prims ADD COLUMN LoopedSound char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
401 | ALTER TABLE prims ADD COLUMN LoopedSoundGain float not null default 0.0; | ||
402 | ALTER TABLE prims ADD COLUMN TextureAnimation blob; | ||
403 | ALTER TABLE prims ADD COLUMN OmegaX float not null default 0.0; | ||
404 | ALTER TABLE prims ADD COLUMN OmegaY float not null default 0.0; | ||
405 | ALTER TABLE prims ADD COLUMN OmegaZ float not null default 0.0; | ||
406 | ALTER TABLE prims ADD COLUMN CameraEyeOffsetX float not null default 0.0; | ||
407 | ALTER TABLE prims ADD COLUMN CameraEyeOffsetY float not null default 0.0; | ||
408 | ALTER TABLE prims ADD COLUMN CameraEyeOffsetZ float not null default 0.0; | ||
409 | ALTER TABLE prims ADD COLUMN CameraAtOffsetX float not null default 0.0; | ||
410 | ALTER TABLE prims ADD COLUMN CameraAtOffsetY float not null default 0.0; | ||
411 | ALTER TABLE prims ADD COLUMN CameraAtOffsetZ float not null default 0.0; | ||
412 | ALTER TABLE prims ADD COLUMN ForceMouselook tinyint not null default 0; | ||
413 | ALTER TABLE prims ADD COLUMN ScriptAccessPin integer not null default 0; | ||
414 | ALTER TABLE prims ADD COLUMN AllowedDrop tinyint not null default 0; | ||
415 | ALTER TABLE prims ADD COLUMN DieAtEdge tinyint not null default 0; | ||
416 | ALTER TABLE prims ADD COLUMN SalePrice integer not null default 10; | ||
417 | ALTER TABLE prims ADD COLUMN SaleType tinyint not null default 0; | ||
418 | |||
419 | COMMIT; | ||
420 | |||
421 | |||
422 | :VERSION 17 #--------------------- | ||
423 | |||
424 | BEGIN; | ||
425 | |||
426 | ALTER TABLE prims ADD COLUMN ColorR integer not null default 0; | ||
427 | ALTER TABLE prims ADD COLUMN ColorG integer not null default 0; | ||
428 | ALTER TABLE prims ADD COLUMN ColorB integer not null default 0; | ||
429 | ALTER TABLE prims ADD COLUMN ColorA integer not null default 0; | ||
430 | ALTER TABLE prims ADD COLUMN ParticleSystem blob; | ||
431 | |||
432 | COMMIT; | ||
433 | |||
434 | |||
435 | :VERSION 18 #--------------------- | ||
436 | |||
437 | begin; | ||
438 | |||
439 | ALTER TABLE prims ADD COLUMN ClickAction tinyint NOT NULL default 0; | ||
440 | |||
441 | commit; | ||
442 | |||
443 | :VERSION 19 #--------------------- | ||
444 | |||
445 | begin; | ||
446 | |||
447 | ALTER TABLE prims ADD COLUMN Material tinyint NOT NULL default 3; | ||
448 | |||
449 | commit; | ||
450 | |||
451 | |||
452 | :VERSION 20 #--------------------- | ||
453 | |||
454 | begin; | ||
455 | |||
456 | ALTER TABLE land ADD COLUMN OtherCleanTime integer NOT NULL default 0; | ||
457 | ALTER TABLE land ADD COLUMN Dwell integer NOT NULL default 0; | ||
458 | |||
459 | commit; | ||
460 | |||
461 | :VERSION 21 #--------------------- | ||
462 | |||
463 | begin; | ||
464 | |||
465 | ALTER TABLE regionsettings ADD COLUMN sunvectorx double NOT NULL default 0; | ||
466 | ALTER TABLE regionsettings ADD COLUMN sunvectory double NOT NULL default 0; | ||
467 | ALTER TABLE regionsettings ADD COLUMN sunvectorz double NOT NULL default 0; | ||
468 | |||
469 | commit; | ||
470 | |||
471 | |||
472 | :VERSION 22 #--------------------- | ||
473 | |||
474 | BEGIN; | ||
475 | |||
476 | ALTER TABLE prims ADD COLUMN CollisionSound char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
477 | ALTER TABLE prims ADD COLUMN CollisionSoundVolume float not null default 0.0; | ||
478 | |||
479 | COMMIT; | ||
480 | |||
481 | :VERSION 23 #--------------------- | ||
482 | |||
483 | BEGIN; | ||
484 | |||
485 | ALTER TABLE prims ADD COLUMN LinkNumber integer not null default 0; | ||
486 | |||
487 | COMMIT; | ||
488 | |||
489 | :VERSION 24 #--------------------- | ||
490 | |||
491 | BEGIN; | ||
492 | |||
493 | alter table regionsettings change column `object_bonus` `object_bonus` double NOT NULL; | ||
494 | alter table regionsettings change column `elevation_1_nw` `elevation_1_nw` double NOT NULL; | ||
495 | alter table regionsettings change column `elevation_2_nw` `elevation_2_nw` double NOT NULL; | ||
496 | alter table regionsettings change column `elevation_1_ne` `elevation_1_ne` double NOT NULL; | ||
497 | alter table regionsettings change column `elevation_2_ne` `elevation_2_ne` double NOT NULL; | ||
498 | alter table regionsettings change column `elevation_1_se` `elevation_1_se` double NOT NULL; | ||
499 | alter table regionsettings change column `elevation_2_se` `elevation_2_se` double NOT NULL; | ||
500 | alter table regionsettings change column `elevation_1_sw` `elevation_1_sw` double NOT NULL; | ||
501 | alter table regionsettings change column `elevation_2_sw` `elevation_2_sw` double NOT NULL; | ||
502 | alter table regionsettings change column `water_height` `water_height` double NOT NULL; | ||
503 | alter table regionsettings change column `terrain_raise_limit` `terrain_raise_limit` double NOT NULL; | ||
504 | alter table regionsettings change column `terrain_lower_limit` `terrain_lower_limit` double NOT NULL; | ||
505 | alter table regionsettings change column `sun_position` `sun_position` double NOT NULL; | ||
506 | |||
507 | COMMIT; | ||
508 | |||
509 | |||
510 | :VERSION 25 #--------------------- | ||
511 | |||
512 | BEGIN; | ||
513 | |||
514 | alter table prims change column `PositionX` `PositionX` double default NULL; | ||
515 | alter table prims change column `PositionY` `PositionY` double default NULL; | ||
516 | alter table prims change column `PositionZ` `PositionZ` double default NULL; | ||
517 | alter table prims change column `GroupPositionX` `GroupPositionX` double default NULL; | ||
518 | alter table prims change column `GroupPositionY` `GroupPositionY` double default NULL; | ||
519 | alter table prims change column `GroupPositionZ` `GroupPositionZ` double default NULL; | ||
520 | alter table prims change column `VelocityX` `VelocityX` double default NULL; | ||
521 | alter table prims change column `VelocityY` `VelocityY` double default NULL; | ||
522 | alter table prims change column `VelocityZ` `VelocityZ` double default NULL; | ||
523 | alter table prims change column `AngularVelocityX` `AngularVelocityX` double default NULL; | ||
524 | alter table prims change column `AngularVelocityY` `AngularVelocityY` double default NULL; | ||
525 | alter table prims change column `AngularVelocityZ` `AngularVelocityZ` double default NULL; | ||
526 | alter table prims change column `AccelerationX` `AccelerationX` double default NULL; | ||
527 | alter table prims change column `AccelerationY` `AccelerationY` double default NULL; | ||
528 | alter table prims change column `AccelerationZ` `AccelerationZ` double default NULL; | ||
529 | alter table prims change column `RotationX` `RotationX` double default NULL; | ||
530 | alter table prims change column `RotationY` `RotationY` double default NULL; | ||
531 | alter table prims change column `RotationZ` `RotationZ` double default NULL; | ||
532 | alter table prims change column `RotationW` `RotationW` double default NULL; | ||
533 | alter table prims change column `SitTargetOffsetX` `SitTargetOffsetX` double default NULL; | ||
534 | alter table prims change column `SitTargetOffsetY` `SitTargetOffsetY` double default NULL; | ||
535 | alter table prims change column `SitTargetOffsetZ` `SitTargetOffsetZ` double default NULL; | ||
536 | alter table prims change column `SitTargetOrientW` `SitTargetOrientW` double default NULL; | ||
537 | alter table prims change column `SitTargetOrientX` `SitTargetOrientX` double default NULL; | ||
538 | alter table prims change column `SitTargetOrientY` `SitTargetOrientY` double default NULL; | ||
539 | alter table prims change column `SitTargetOrientZ` `SitTargetOrientZ` double default NULL; | ||
540 | alter table prims change column `LoopedSoundGain` `LoopedSoundGain` double NOT NULL default '0'; | ||
541 | alter table prims change column `OmegaX` `OmegaX` double NOT NULL default '0'; | ||
542 | alter table prims change column `OmegaY` `OmegaY` double NOT NULL default '0'; | ||
543 | alter table prims change column `OmegaZ` `OmegaZ` double NOT NULL default '0'; | ||
544 | alter table prims change column `CameraEyeOffsetX` `CameraEyeOffsetX` double NOT NULL default '0'; | ||
545 | alter table prims change column `CameraEyeOffsetY` `CameraEyeOffsetY` double NOT NULL default '0'; | ||
546 | alter table prims change column `CameraEyeOffsetZ` `CameraEyeOffsetZ` double NOT NULL default '0'; | ||
547 | alter table prims change column `CameraAtOffsetX` `CameraAtOffsetX` double NOT NULL default '0'; | ||
548 | alter table prims change column `CameraAtOffsetY` `CameraAtOffsetY` double NOT NULL default '0'; | ||
549 | alter table prims change column `CameraAtOffsetZ` `CameraAtOffsetZ` double NOT NULL default '0'; | ||
550 | alter table prims change column `CollisionSoundVolume` `CollisionSoundVolume` double NOT NULL default '0'; | ||
551 | |||
552 | alter table primshapes change column `ScaleX` `ScaleX` double NOT NULL default '0'; | ||
553 | alter table primshapes change column `ScaleY` `ScaleY` double NOT NULL default '0'; | ||
554 | alter table primshapes change column `ScaleZ` `ScaleZ` double NOT NULL default '0'; | ||
555 | |||
556 | COMMIT; | ||
557 | |||
558 | :VERSION 26 #--------------------- | ||
559 | |||
560 | begin; | ||
561 | |||
562 | alter table prims change column `PositionX` `PositionX` double default NULL; | ||
563 | alter table prims change column `PositionY` `PositionY` double default NULL; | ||
564 | alter table prims change column `PositionZ` `PositionZ` double default NULL; | ||
565 | alter table prims change column `GroupPositionX` `GroupPositionX` double default NULL; | ||
566 | alter table prims change column `GroupPositionY` `GroupPositionY` double default NULL; | ||
567 | alter table prims change column `GroupPositionZ` `GroupPositionZ` double default NULL; | ||
568 | alter table prims change column `VelocityX` `VelocityX` double default NULL; | ||
569 | alter table prims change column `VelocityY` `VelocityY` double default NULL; | ||
570 | alter table prims change column `VelocityZ` `VelocityZ` double default NULL; | ||
571 | alter table prims change column `AngularVelocityX` `AngularVelocityX` double default NULL; | ||
572 | alter table prims change column `AngularVelocityY` `AngularVelocityY` double default NULL; | ||
573 | alter table prims change column `AngularVelocityZ` `AngularVelocityZ` double default NULL; | ||
574 | alter table prims change column `AccelerationX` `AccelerationX` double default NULL; | ||
575 | alter table prims change column `AccelerationY` `AccelerationY` double default NULL; | ||
576 | alter table prims change column `AccelerationZ` `AccelerationZ` double default NULL; | ||
577 | alter table prims change column `RotationX` `RotationX` double default NULL; | ||
578 | alter table prims change column `RotationY` `RotationY` double default NULL; | ||
579 | alter table prims change column `RotationZ` `RotationZ` double default NULL; | ||
580 | alter table prims change column `RotationW` `RotationW` double default NULL; | ||
581 | alter table prims change column `SitTargetOffsetX` `SitTargetOffsetX` double default NULL; | ||
582 | alter table prims change column `SitTargetOffsetY` `SitTargetOffsetY` double default NULL; | ||
583 | alter table prims change column `SitTargetOffsetZ` `SitTargetOffsetZ` double default NULL; | ||
584 | alter table prims change column `SitTargetOrientW` `SitTargetOrientW` double default NULL; | ||
585 | alter table prims change column `SitTargetOrientX` `SitTargetOrientX` double default NULL; | ||
586 | alter table prims change column `SitTargetOrientY` `SitTargetOrientY` double default NULL; | ||
587 | alter table prims change column `SitTargetOrientZ` `SitTargetOrientZ` double default NULL; | ||
588 | alter table prims change column `LoopedSoundGain` `LoopedSoundGain` double NOT NULL default '0'; | ||
589 | alter table prims change column `OmegaX` `OmegaX` double NOT NULL default '0'; | ||
590 | alter table prims change column `OmegaY` `OmegaY` double NOT NULL default '0'; | ||
591 | alter table prims change column `OmegaZ` `OmegaZ` double NOT NULL default '0'; | ||
592 | alter table prims change column `CameraEyeOffsetX` `CameraEyeOffsetX` double NOT NULL default '0'; | ||
593 | alter table prims change column `CameraEyeOffsetY` `CameraEyeOffsetY` double NOT NULL default '0'; | ||
594 | alter table prims change column `CameraEyeOffsetZ` `CameraEyeOffsetZ` double NOT NULL default '0'; | ||
595 | alter table prims change column `CameraAtOffsetX` `CameraAtOffsetX` double NOT NULL default '0'; | ||
596 | alter table prims change column `CameraAtOffsetY` `CameraAtOffsetY` double NOT NULL default '0'; | ||
597 | alter table prims change column `CameraAtOffsetZ` `CameraAtOffsetZ` double NOT NULL default '0'; | ||
598 | alter table prims change column `CollisionSoundVolume` `CollisionSoundVolume` double NOT NULL default '0'; | ||
599 | |||
600 | commit; | ||
601 | |||
602 | :VERSION 27 #--------------------- | ||
603 | |||
604 | BEGIN; | ||
605 | |||
606 | ALTER TABLE prims DROP COLUMN ParentID; | ||
607 | |||
608 | COMMIT; | ||
609 | |||
610 | :VERSION 28 #--------------------- | ||
611 | |||
612 | BEGIN; | ||
613 | |||
614 | update terrain | ||
615 | set RegionUUID = concat(substr(RegionUUID, 1, 8), "-", substr(RegionUUID, 9, 4), "-", substr(RegionUUID, 13, 4), "-", substr(RegionUUID, 17, 4), "-", substr(RegionUUID, 21, 12)) | ||
616 | where RegionUUID not like '%-%'; | ||
617 | |||
618 | |||
619 | update landaccesslist | ||
620 | set LandUUID = concat(substr(LandUUID, 1, 8), "-", substr(LandUUID, 9, 4), "-", substr(LandUUID, 13, 4), "-", substr(LandUUID, 17, 4), "-", substr(LandUUID, 21, 12)) | ||
621 | where LandUUID not like '%-%'; | ||
622 | |||
623 | update landaccesslist | ||
624 | set AccessUUID = concat(substr(AccessUUID, 1, 8), "-", substr(AccessUUID, 9, 4), "-", substr(AccessUUID, 13, 4), "-", substr(AccessUUID, 17, 4), "-", substr(AccessUUID, 21, 12)) | ||
625 | where AccessUUID not like '%-%'; | ||
626 | |||
627 | |||
628 | update prims | ||
629 | set UUID = concat(substr(UUID, 1, 8), "-", substr(UUID, 9, 4), "-", substr(UUID, 13, 4), "-", substr(UUID, 17, 4), "-", substr(UUID, 21, 12)) | ||
630 | where UUID not like '%-%'; | ||
631 | |||
632 | update prims | ||
633 | set RegionUUID = concat(substr(RegionUUID, 1, 8), "-", substr(RegionUUID, 9, 4), "-", substr(RegionUUID, 13, 4), "-", substr(RegionUUID, 17, 4), "-", substr(RegionUUID, 21, 12)) | ||
634 | where RegionUUID not like '%-%'; | ||
635 | |||
636 | update prims | ||
637 | set SceneGroupID = concat(substr(SceneGroupID, 1, 8), "-", substr(SceneGroupID, 9, 4), "-", substr(SceneGroupID, 13, 4), "-", substr(SceneGroupID, 17, 4), "-", substr(SceneGroupID, 21, 12)) | ||
638 | where SceneGroupID not like '%-%'; | ||
639 | |||
640 | update prims | ||
641 | set CreatorID = concat(substr(CreatorID, 1, 8), "-", substr(CreatorID, 9, 4), "-", substr(CreatorID, 13, 4), "-", substr(CreatorID, 17, 4), "-", substr(CreatorID, 21, 12)) | ||
642 | where CreatorID not like '%-%'; | ||
643 | |||
644 | update prims | ||
645 | set OwnerID = concat(substr(OwnerID, 1, 8), "-", substr(OwnerID, 9, 4), "-", substr(OwnerID, 13, 4), "-", substr(OwnerID, 17, 4), "-", substr(OwnerID, 21, 12)) | ||
646 | where OwnerID not like '%-%'; | ||
647 | |||
648 | update prims | ||
649 | set GroupID = concat(substr(GroupID, 1, 8), "-", substr(GroupID, 9, 4), "-", substr(GroupID, 13, 4), "-", substr(GroupID, 17, 4), "-", substr(GroupID, 21, 12)) | ||
650 | where GroupID not like '%-%'; | ||
651 | |||
652 | update prims | ||
653 | set LastOwnerID = concat(substr(LastOwnerID, 1, 8), "-", substr(LastOwnerID, 9, 4), "-", substr(LastOwnerID, 13, 4), "-", substr(LastOwnerID, 17, 4), "-", substr(LastOwnerID, 21, 12)) | ||
654 | where LastOwnerID not like '%-%'; | ||
655 | |||
656 | |||
657 | update primshapes | ||
658 | set UUID = concat(substr(UUID, 1, 8), "-", substr(UUID, 9, 4), "-", substr(UUID, 13, 4), "-", substr(UUID, 17, 4), "-", substr(UUID, 21, 12)) | ||
659 | where UUID not like '%-%'; | ||
660 | |||
661 | |||
662 | update land | ||
663 | set UUID = concat(substr(UUID, 1, 8), "-", substr(UUID, 9, 4), "-", substr(UUID, 13, 4), "-", substr(UUID, 17, 4), "-", substr(UUID, 21, 12)) | ||
664 | where UUID not like '%-%'; | ||
665 | |||
666 | update land | ||
667 | set RegionUUID = concat(substr(RegionUUID, 1, 8), "-", substr(RegionUUID, 9, 4), "-", substr(RegionUUID, 13, 4), "-", substr(RegionUUID, 17, 4), "-", substr(RegionUUID, 21, 12)) | ||
668 | where RegionUUID not like '%-%'; | ||
669 | |||
670 | update land | ||
671 | set OwnerUUID = concat(substr(OwnerUUID, 1, 8), "-", substr(OwnerUUID, 9, 4), "-", substr(OwnerUUID, 13, 4), "-", substr(OwnerUUID, 17, 4), "-", substr(OwnerUUID, 21, 12)) | ||
672 | where OwnerUUID not like '%-%'; | ||
673 | |||
674 | update land | ||
675 | set GroupUUID = concat(substr(GroupUUID, 1, 8), "-", substr(GroupUUID, 9, 4), "-", substr(GroupUUID, 13, 4), "-", substr(GroupUUID, 17, 4), "-", substr(GroupUUID, 21, 12)) | ||
676 | where GroupUUID not like '%-%'; | ||
677 | |||
678 | update land | ||
679 | set MediaTextureUUID = concat(substr(MediaTextureUUID, 1, 8), "-", substr(MediaTextureUUID, 9, 4), "-", substr(MediaTextureUUID, 13, 4), "-", substr(MediaTextureUUID, 17, 4), "-", substr(MediaTextureUUID, 21, 12)) | ||
680 | where MediaTextureUUID not like '%-%'; | ||
681 | |||
682 | update land | ||
683 | set SnapshotUUID = concat(substr(SnapshotUUID, 1, 8), "-", substr(SnapshotUUID, 9, 4), "-", substr(SnapshotUUID, 13, 4), "-", substr(SnapshotUUID, 17, 4), "-", substr(SnapshotUUID, 21, 12)) | ||
684 | where SnapshotUUID not like '%-%'; | ||
685 | |||
686 | update land | ||
687 | set AuthbuyerID = concat(substr(AuthbuyerID, 1, 8), "-", substr(AuthbuyerID, 9, 4), "-", substr(AuthbuyerID, 13, 4), "-", substr(AuthbuyerID, 17, 4), "-", substr(AuthbuyerID, 21, 12)) | ||
688 | where AuthbuyerID not like '%-%'; | ||
689 | |||
690 | COMMIT; | ||
691 | |||
692 | :VERSION 29 #--------------------- | ||
693 | |||
694 | BEGIN; | ||
695 | |||
696 | ALTER TABLE prims ADD COLUMN PassTouches tinyint not null default 0; | ||
697 | |||
698 | COMMIT; | ||
699 | |||
700 | :VERSION 30 #--------------------- | ||
701 | |||
702 | BEGIN; | ||
703 | |||
704 | ALTER TABLE regionsettings ADD COLUMN loaded_creation_date varchar(20) default NULL; | ||
705 | ALTER TABLE regionsettings ADD COLUMN loaded_creation_time varchar(20) default NULL; | ||
706 | ALTER TABLE regionsettings ADD COLUMN loaded_creation_id varchar(64) default NULL; | ||
707 | |||
708 | COMMIT; | ||
709 | |||
710 | :VERSION 31 #--------------------- | ||
711 | |||
712 | BEGIN; | ||
713 | |||
714 | ALTER TABLE regionsettings DROP COLUMN loaded_creation_date; | ||
715 | ALTER TABLE regionsettings DROP COLUMN loaded_creation_time; | ||
716 | ALTER TABLE regionsettings ADD COLUMN loaded_creation_datetime int unsigned NOT NULL default 0; | ||
717 | |||
718 | COMMIT; | ||
719 | |||
720 | :VERSION 32 | ||
721 | |||
722 | BEGIN; | ||
723 | CREATE TABLE `regionwindlight` ( | ||
724 | `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', | ||
725 | `water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000', | ||
726 | `water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000', | ||
727 | `water_color_b` float(9,6) unsigned NOT NULL DEFAULT '64.000000', | ||
728 | `water_fog_density_exponent` float(3,1) unsigned NOT NULL DEFAULT '4.0', | ||
729 | `underwater_fog_modifier` float(3,2) unsigned NOT NULL DEFAULT '0.25', | ||
730 | `reflection_wavelet_scale_1` float(3,1) unsigned NOT NULL DEFAULT '2.0', | ||
731 | `reflection_wavelet_scale_2` float(3,1) unsigned NOT NULL DEFAULT '2.0', | ||
732 | `reflection_wavelet_scale_3` float(3,1) unsigned NOT NULL DEFAULT '2.0', | ||
733 | `fresnel_scale` float(3,2) unsigned NOT NULL DEFAULT '0.40', | ||
734 | `fresnel_offset` float(3,2) unsigned NOT NULL DEFAULT '0.50', | ||
735 | `refract_scale_above` float(3,2) unsigned NOT NULL DEFAULT '0.03', | ||
736 | `refract_scale_below` float(3,2) unsigned NOT NULL DEFAULT '0.20', | ||
737 | `blur_multiplier` float(4,3) unsigned NOT NULL DEFAULT '0.040', | ||
738 | `big_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.05', | ||
739 | `big_wave_direction_y` float(3,2) NOT NULL DEFAULT '-0.42', | ||
740 | `little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11', | ||
741 | `little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16', | ||
742 | `normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4', | ||
743 | `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.25', | ||
744 | `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.25', | ||
745 | `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.32', | ||
746 | `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.32', | ||
747 | `haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19', | ||
748 | `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.12', | ||
749 | `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.22', | ||
750 | `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.38', | ||
751 | `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.38', | ||
752 | `haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70', | ||
753 | `density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18', | ||
754 | `distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8', | ||
755 | `max_altitude` int(4) unsigned NOT NULL DEFAULT '1605', | ||
756 | `sun_moon_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.24', | ||
757 | `sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26', | ||
758 | `sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30', | ||
759 | `sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30', | ||
760 | `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.317', | ||
761 | `ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
762 | `ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
763 | `ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
764 | `ambient_i` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
765 | `east_angle` float(3,2) unsigned NOT NULL DEFAULT '0.00', | ||
766 | `sun_glow_focus` float(3,2) unsigned NOT NULL DEFAULT '0.10', | ||
767 | `sun_glow_size` float(3,2) unsigned NOT NULL DEFAULT '1.75', | ||
768 | `scene_gamma` float(4,2) unsigned NOT NULL DEFAULT '1.00', | ||
769 | `star_brightness` float(3,2) unsigned NOT NULL DEFAULT '0.00', | ||
770 | `cloud_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
771 | `cloud_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
772 | `cloud_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
773 | `cloud_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
774 | `cloud_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', | ||
775 | `cloud_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', | ||
776 | `cloud_density` float(3,2) unsigned NOT NULL DEFAULT '1.00', | ||
777 | `cloud_coverage` float(3,2) unsigned NOT NULL DEFAULT '0.27', | ||
778 | `cloud_scale` float(3,2) unsigned NOT NULL DEFAULT '0.42', | ||
779 | `cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', | ||
780 | `cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', | ||
781 | `cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12', | ||
782 | `cloud_scroll_x` float(3,2) unsigned NOT NULL DEFAULT '0.20', | ||
783 | `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', | ||
784 | `cloud_scroll_y` float(3,2) unsigned NOT NULL DEFAULT '0.01', | ||
785 | `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', | ||
786 | `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '1', | ||
787 | PRIMARY KEY (`region_id`) | ||
788 | ); | ||
789 | |||
790 | |||
791 | :VERSION 33 #--------------------- | ||
792 | |||
793 | BEGIN; | ||
794 | ALTER TABLE regionsettings ADD map_tile_ID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; | ||
795 | COMMIT; | ||
796 | |||
797 | :VERSION 34 #--------------------- | ||
798 | |||
799 | BEGIN; | ||
800 | ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`; | ||
801 | COMMIT; | ||
802 | |||
803 | :VERSION 35 #--------------------- | ||
804 | |||
805 | BEGIN; | ||
806 | ALTER TABLE prims ADD COLUMN MediaURL varchar(255); | ||
807 | ALTER TABLE primshapes ADD COLUMN Media TEXT; | ||
808 | COMMIT; | ||
809 | |||
810 | :VERSION 36 #--------------------- | ||
811 | |||
812 | BEGIN; | ||
813 | ALTER TABLE `land` ADD COLUMN `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none' ; | ||
814 | ALTER TABLE `land` ADD COLUMN `MediaDescription` VARCHAR(255) NOT NULL DEFAULT ''; | ||
815 | ALTER TABLE `land` ADD COLUMN `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0'; | ||
816 | ALTER TABLE `land` ADD COLUMN `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE; | ||
817 | ALTER TABLE `land` ADD COLUMN `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE; | ||
818 | ALTER TABLE `land` ADD COLUMN `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE; | ||
819 | COMMIT; | ||
820 | |||
821 | :VERSION 37 #--------------------- | ||
822 | |||
823 | BEGIN; | ||
824 | |||
825 | ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; | ||
826 | ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; | ||
827 | |||
828 | COMMIT; | ||
829 | |||
830 | :VERSION 38 #--------------------- | ||
831 | |||
832 | BEGIN; | ||
833 | |||
834 | alter table land ENGINE = MyISAM; | ||
835 | alter table landaccesslist ENGINE = MyISAM; | ||
836 | alter table migrations ENGINE = MyISAM; | ||
837 | alter table primitems ENGINE = MyISAM; | ||
838 | alter table prims ENGINE = MyISAM; | ||
839 | alter table primshapes ENGINE = MyISAM; | ||
840 | alter table regionban ENGINE = MyISAM; | ||
841 | alter table regionsettings ENGINE = MyISAM; | ||
842 | alter table terrain ENGINE = MyISAM; | ||
843 | |||
844 | COMMIT; | ||
845 | |||
846 | :VERSION 39 #--------------- Telehub support | ||
847 | |||
848 | BEGIN; | ||
849 | CREATE TABLE IF NOT EXISTS `spawn_points` ( | ||
850 | `RegionID` varchar(36) COLLATE utf8_unicode_ci NOT NULL, | ||
851 | `Yaw` float NOT NULL, | ||
852 | `Pitch` float NOT NULL, | ||
853 | `Distance` float NOT NULL, | ||
854 | KEY `RegionID` (`RegionID`) | ||
855 | ) ENGINE=Innodb; | ||
856 | |||
857 | ALTER TABLE `regionsettings` ADD COLUMN `TelehubObject` varchar(36) NOT NULL; | ||
858 | COMMIT; | ||
859 | |||
860 | :VERSION 40 #---------------- Parcels for sale | ||
861 | |||
862 | BEGIN; | ||
863 | ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; | ||
864 | COMMIT; | ||
865 | |||
866 | :VERSION 41 #---------------- Timed bans/access | ||
867 | |||
868 | BEGIN; | ||
869 | ALTER TABLE `landaccesslist` ADD COLUMN `Expires` INTEGER NOT NULL DEFAULT 0; | ||
870 | COMMIT; | ||
871 | |||
872 | :VERSION 42 #--------------------- Region Covenant changed time | ||
873 | |||
874 | BEGIN; | ||
875 | ALTER TABLE regionsettings ADD COLUMN covenant_datetime int unsigned NOT NULL DEFAULT '0'; | ||
876 | COMMIT; | ||
877 | |||
878 | :VERSION 43 #--------------------- | ||
879 | |||
880 | BEGIN; | ||
881 | |||
882 | ALTER TABLE `regionsettings` MODIFY COLUMN `TelehubObject` VARCHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; | ||
883 | |||
884 | COMMIT; | ||
885 | |||
886 | :VERSION 44 #--------------------- Environment Settings | ||
887 | |||
888 | BEGIN; | ||
889 | |||
890 | CREATE TABLE `regionenvironment` ( | ||
891 | `region_id` varchar(36) NOT NULL, | ||
892 | `llsd_settings` TEXT NOT NULL, | ||
893 | PRIMARY KEY (`region_id`) | ||
894 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
895 | |||
896 | COMMIT; | ||
897 | |||
898 | :VERSION 45 | ||
899 | |||
900 | BEGIN; | ||
901 | |||
902 | CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`)); | ||
903 | |||
904 | COMMIT; | ||
905 | |||
906 | :VERSION 46 #---------------- Dynamic attributes | ||
907 | |||
908 | BEGIN; | ||
909 | |||
910 | ALTER TABLE prims ADD COLUMN DynAttrs TEXT; | ||
911 | |||
912 | COMMIT; | ||
913 | |||
914 | :VERSION 47 #---------------- Extra physics params | ||
915 | |||
916 | BEGIN; | ||
917 | |||
918 | ALTER TABLE prims ADD COLUMN `PhysicsShapeType` tinyint(4) NOT NULL default '0'; | ||
919 | ALTER TABLE prims ADD COLUMN `Density` double NOT NULL default '1000'; | ||
920 | ALTER TABLE prims ADD COLUMN `GravityModifier` double NOT NULL default '1'; | ||
921 | ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6'; | ||
922 | ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5'; | ||
923 | |||
924 | COMMIT; | ||
925 | |||
926 | :VERSION 48 #---------------- Keyframes | ||
927 | |||
928 | BEGIN; | ||
929 | |||
930 | ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob; | ||
931 | |||
932 | COMMIT; | ||
933 | |||
934 | :VERSION 49 #--------------------- Save attachment info | ||
935 | |||
936 | BEGIN; | ||
937 | ALTER TABLE prims ADD COLUMN AttachedPosX double default 0; | ||
938 | ALTER TABLE prims ADD COLUMN AttachedPosY double default 0; | ||
939 | ALTER TABLE prims ADD COLUMN AttachedPosZ double default 0; | ||
940 | ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0'; | ||
941 | COMMIT; | ||
942 | |||
943 | :VERSION 50 #---- Change LandFlags to unsigned | ||
944 | |||
945 | BEGIN; | ||
946 | |||
947 | ALTER TABLE land CHANGE COLUMN LandFlags LandFlags int unsigned default null; | ||
948 | |||
949 | COMMIT; | ||
950 | |||
diff --git a/OpenSim/Data/MySQL/Resources/UserAccount.migrations b/OpenSim/Data/MySQL/Resources/UserAccount.migrations new file mode 100644 index 0000000..84011e6 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/UserAccount.migrations | |||
@@ -0,0 +1,47 @@ | |||
1 | :VERSION 1 # ------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `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), | ||
11 | `ServiceURLs` TEXT, | ||
12 | `Created` INT(11) | ||
13 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
14 | |||
15 | COMMIT; | ||
16 | |||
17 | :VERSION 2 # ------------------------- | ||
18 | |||
19 | BEGIN; | ||
20 | |||
21 | INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, lastname AS LastName, email as Email, CONCAT('AssetServerURI=', userAssetURI, ' InventoryServerURI=', userInventoryURI, ' GatewayURI= HomeURI=') AS ServiceURLs, created as Created FROM users; | ||
22 | |||
23 | COMMIT; | ||
24 | |||
25 | :VERSION 3 # ------------------------- | ||
26 | |||
27 | BEGIN; | ||
28 | |||
29 | CREATE UNIQUE INDEX PrincipalID ON UserAccounts(PrincipalID); | ||
30 | CREATE INDEX Email ON UserAccounts(Email); | ||
31 | CREATE INDEX FirstName ON UserAccounts(FirstName); | ||
32 | CREATE INDEX LastName ON UserAccounts(LastName); | ||
33 | CREATE INDEX Name ON UserAccounts(FirstName,LastName); | ||
34 | |||
35 | COMMIT; | ||
36 | |||
37 | :VERSION 4 # ------------------------- | ||
38 | |||
39 | BEGIN; | ||
40 | |||
41 | ALTER TABLE UserAccounts ADD COLUMN UserLevel integer NOT NULL DEFAULT 0; | ||
42 | ALTER TABLE UserAccounts ADD COLUMN UserFlags integer NOT NULL DEFAULT 0; | ||
43 | ALTER TABLE UserAccounts ADD COLUMN UserTitle varchar(64) NOT NULL DEFAULT ''; | ||
44 | |||
45 | COMMIT; | ||
46 | |||
47 | |||
diff --git a/OpenSim/Data/MySQL/Resources/UserProfiles.migrations b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations new file mode 100644 index 0000000..87e99fa --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations | |||
@@ -0,0 +1,98 @@ | |||
1 | :VERSION 1 # ------------------------------- | ||
2 | |||
3 | begin; | ||
4 | |||
5 | CREATE 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=InnoDB DEFAULT CHARSET=latin1; | ||
23 | |||
24 | |||
25 | CREATE 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 | |||
33 | CREATE 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 | PRIMARY KEY (`pickuuid`) | ||
48 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
49 | |||
50 | |||
51 | CREATE TABLE IF NOT EXISTS `userprofile` ( | ||
52 | `useruuid` varchar(36) NOT NULL, | ||
53 | `profilePartner` varchar(36) NOT NULL, | ||
54 | `profileAllowPublish` binary(1) NOT NULL, | ||
55 | `profileMaturePublish` binary(1) NOT NULL, | ||
56 | `profileURL` varchar(255) NOT NULL, | ||
57 | `profileWantToMask` int(3) NOT NULL, | ||
58 | `profileWantToText` text NOT NULL, | ||
59 | `profileSkillsMask` int(3) NOT NULL, | ||
60 | `profileSkillsText` text NOT NULL, | ||
61 | `profileLanguages` text NOT NULL, | ||
62 | `profileImage` varchar(36) NOT NULL, | ||
63 | `profileAboutText` text NOT NULL, | ||
64 | `profileFirstImage` varchar(36) NOT NULL, | ||
65 | `profileFirstText` text NOT NULL, | ||
66 | PRIMARY KEY (`useruuid`) | ||
67 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
68 | |||
69 | commit; | ||
70 | |||
71 | :VERSION 2 # ------------------------------- | ||
72 | |||
73 | begin; | ||
74 | CREATE TABLE IF NOT EXISTS `userdata` ( | ||
75 | `UserId` char(36) NOT NULL, | ||
76 | `TagId` varchar(64) NOT NULL, | ||
77 | `DataKey` varchar(255), | ||
78 | `DataVal` varchar(255), | ||
79 | PRIMARY KEY (`UserId`,`TagId`) | ||
80 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
81 | |||
82 | commit; | ||
83 | |||
84 | :VERSION 3 # ------------------------------- | ||
85 | begin; | ||
86 | CREATE TABLE IF NOT EXISTS `usersettings` ( | ||
87 | `useruuid` varchar(36) NOT NULL, | ||
88 | `imviaemail` enum('true','false') NOT NULL, | ||
89 | `visible` enum('true','false') NOT NULL, | ||
90 | `email` varchar(254) NOT NULL, | ||
91 | PRIMARY KEY (`useruuid`) | ||
92 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
93 | commit; | ||
94 | |||
95 | :VERSION 4 # ------------------------------- | ||
96 | begin; | ||
97 | ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255); | ||
98 | commit; | ||
diff --git a/OpenSim/Data/MySQL/Resources/UserStore.migrations b/OpenSim/Data/MySQL/Resources/UserStore.migrations new file mode 100644 index 0000000..f054611 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/UserStore.migrations | |||
@@ -0,0 +1,168 @@ | |||
1 | :VERSION 1 # ----------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | SET FOREIGN_KEY_CHECKS=0; | ||
6 | -- ---------------------------- | ||
7 | -- Table structure for agents | ||
8 | -- ---------------------------- | ||
9 | CREATE TABLE `agents` ( | ||
10 | `UUID` varchar(36) NOT NULL, | ||
11 | `sessionID` varchar(36) NOT NULL, | ||
12 | `secureSessionID` varchar(36) NOT NULL, | ||
13 | `agentIP` varchar(16) NOT NULL, | ||
14 | `agentPort` int(11) NOT NULL, | ||
15 | `agentOnline` tinyint(4) NOT NULL, | ||
16 | `loginTime` int(11) NOT NULL, | ||
17 | `logoutTime` int(11) NOT NULL, | ||
18 | `currentRegion` varchar(36) NOT NULL, | ||
19 | `currentHandle` bigint(20) unsigned NOT NULL, | ||
20 | `currentPos` varchar(64) NOT NULL, | ||
21 | PRIMARY KEY (`UUID`), | ||
22 | UNIQUE KEY `session` (`sessionID`), | ||
23 | UNIQUE KEY `ssession` (`secureSessionID`) | ||
24 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
25 | |||
26 | -- Create schema avatar_appearance | ||
27 | -- | ||
28 | |||
29 | CREATE TABLE `avatarappearance` ( | ||
30 | Owner char(36) NOT NULL, | ||
31 | Serial int(10) unsigned NOT NULL, | ||
32 | Visual_Params blob NOT NULL, | ||
33 | Texture blob NOT NULL, | ||
34 | Avatar_Height float NOT NULL, | ||
35 | Body_Item char(36) NOT NULL, | ||
36 | Body_Asset char(36) NOT NULL, | ||
37 | Skin_Item char(36) NOT NULL, | ||
38 | Skin_Asset char(36) NOT NULL, | ||
39 | Hair_Item char(36) NOT NULL, | ||
40 | Hair_Asset char(36) NOT NULL, | ||
41 | Eyes_Item char(36) NOT NULL, | ||
42 | Eyes_Asset char(36) NOT NULL, | ||
43 | Shirt_Item char(36) NOT NULL, | ||
44 | Shirt_Asset char(36) NOT NULL, | ||
45 | Pants_Item char(36) NOT NULL, | ||
46 | Pants_Asset char(36) NOT NULL, | ||
47 | Shoes_Item char(36) NOT NULL, | ||
48 | Shoes_Asset char(36) NOT NULL, | ||
49 | Socks_Item char(36) NOT NULL, | ||
50 | Socks_Asset char(36) NOT NULL, | ||
51 | Jacket_Item char(36) NOT NULL, | ||
52 | Jacket_Asset char(36) NOT NULL, | ||
53 | Gloves_Item char(36) NOT NULL, | ||
54 | Gloves_Asset char(36) NOT NULL, | ||
55 | Undershirt_Item char(36) NOT NULL, | ||
56 | Undershirt_Asset char(36) NOT NULL, | ||
57 | Underpants_Item char(36) NOT NULL, | ||
58 | Underpants_Asset char(36) NOT NULL, | ||
59 | Skirt_Item char(36) NOT NULL, | ||
60 | Skirt_Asset char(36) NOT NULL, | ||
61 | PRIMARY KEY (`Owner`) | ||
62 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
63 | |||
64 | SET FOREIGN_KEY_CHECKS=0; | ||
65 | -- ---------------------------- | ||
66 | -- Table structure for users | ||
67 | -- ---------------------------- | ||
68 | CREATE TABLE `userfriends` ( | ||
69 | `ownerID` VARCHAR(37) NOT NULL, | ||
70 | `friendID` VARCHAR(37) NOT NULL, | ||
71 | `friendPerms` INT NOT NULL, | ||
72 | `datetimestamp` INT NOT NULL, | ||
73 | UNIQUE KEY (`ownerID`, `friendID`) | ||
74 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
75 | -- ---------------------------- | ||
76 | -- Table structure for users | ||
77 | -- ---------------------------- | ||
78 | CREATE TABLE `users` ( | ||
79 | `UUID` varchar(36) NOT NULL default '', | ||
80 | `username` varchar(32) NOT NULL, | ||
81 | `lastname` varchar(32) NOT NULL, | ||
82 | `passwordHash` varchar(32) NOT NULL, | ||
83 | `passwordSalt` varchar(32) NOT NULL, | ||
84 | `homeRegion` bigint(20) unsigned default NULL, | ||
85 | `homeLocationX` float default NULL, | ||
86 | `homeLocationY` float default NULL, | ||
87 | `homeLocationZ` float default NULL, | ||
88 | `homeLookAtX` float default NULL, | ||
89 | `homeLookAtY` float default NULL, | ||
90 | `homeLookAtZ` float default NULL, | ||
91 | `created` int(11) NOT NULL, | ||
92 | `lastLogin` int(11) NOT NULL, | ||
93 | `userInventoryURI` varchar(255) default NULL, | ||
94 | `userAssetURI` varchar(255) default NULL, | ||
95 | `profileCanDoMask` int(10) unsigned default NULL, | ||
96 | `profileWantDoMask` int(10) unsigned default NULL, | ||
97 | `profileAboutText` text, | ||
98 | `profileFirstText` text, | ||
99 | `profileImage` varchar(36) default NULL, | ||
100 | `profileFirstImage` varchar(36) default NULL, | ||
101 | `webLoginKey` varchar(36) default NULL, | ||
102 | PRIMARY KEY (`UUID`), | ||
103 | UNIQUE KEY `usernames` (`username`,`lastname`) | ||
104 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
105 | |||
106 | -- ---------------------------- | ||
107 | -- Records | ||
108 | -- ---------------------------- | ||
109 | COMMIT; | ||
110 | |||
111 | :VERSION 2 # ----------------------------- | ||
112 | |||
113 | BEGIN; | ||
114 | |||
115 | ALTER TABLE users add homeRegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; | ||
116 | |||
117 | COMMIT; | ||
118 | |||
119 | :VERSION 3 # ----------------------------- | ||
120 | |||
121 | BEGIN; | ||
122 | |||
123 | ALTER TABLE users add userFlags integer NOT NULL default 0; | ||
124 | ALTER TABLE users add godLevel integer NOT NULL default 0; | ||
125 | |||
126 | COMMIT; | ||
127 | |||
128 | :VERSION 4 # ----------------------------- | ||
129 | |||
130 | BEGIN; | ||
131 | |||
132 | ALTER TABLE users add customType varchar(32) not null default ''; | ||
133 | ALTER TABLE users add partner char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
134 | |||
135 | COMMIT; | ||
136 | |||
137 | :VERSION 5 # ----------------------------- | ||
138 | |||
139 | BEGIN; | ||
140 | |||
141 | CREATE TABLE `avatarattachments` (`UUID` char(36) NOT NULL, `attachpoint` int(11) NOT NULL, `item` char(36) NOT NULL, `asset` char(36) NOT NULL) ENGINE=InnoDB; | ||
142 | |||
143 | COMMIT; | ||
144 | |||
145 | :VERSION 6 # ----------------------------- | ||
146 | |||
147 | BEGIN; | ||
148 | |||
149 | ALTER TABLE agents add currentLookAt varchar(36) not null default ''; | ||
150 | |||
151 | COMMIT; | ||
152 | |||
153 | :VERSION 7 # ----------------------------- | ||
154 | |||
155 | BEGIN; | ||
156 | |||
157 | ALTER TABLE users add email varchar(250); | ||
158 | |||
159 | COMMIT; | ||
160 | |||
161 | :VERSION 8 # ----------------------------- | ||
162 | |||
163 | BEGIN; | ||
164 | |||
165 | ALTER TABLE users add scopeID char(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
166 | |||
167 | COMMIT; | ||
168 | |||
diff --git a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations new file mode 100644 index 0000000..9459e3e --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations | |||
@@ -0,0 +1,32 @@ | |||
1 | # ----------------- | ||
2 | :VERSION 1 | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE `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=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1'; | ||
20 | |||
21 | CREATE TABLE `XAssetsData` ( | ||
22 | `Hash` binary(32) NOT NULL, | ||
23 | `Data` longblob NOT NULL, | ||
24 | PRIMARY KEY (`hash`) | ||
25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1'; | ||
26 | |||
27 | COMMIT; | ||
28 | |||
29 | :VERSION 2 | ||
30 | |||
31 | BEGIN; | ||
32 | COMMIT; | ||
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..9e6f1c1 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations | |||
@@ -0,0 +1,115 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE `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; | ||
22 | |||
23 | |||
24 | CREATE TABLE `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; | ||
35 | |||
36 | |||
37 | CREATE TABLE `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; | ||
47 | |||
48 | |||
49 | CREATE TABLE `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; | ||
56 | |||
57 | |||
58 | CREATE TABLE `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; | ||
67 | |||
68 | |||
69 | CREATE TABLE `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; | ||
85 | |||
86 | CREATE TABLE `os_groups_principals` ( | ||
87 | `PrincipalID` VARCHAR(255) NOT NULL default '', | ||
88 | `ActiveGroupID` char(36) NOT NULL default '', | ||
89 | PRIMARY KEY (`PrincipalID`) | ||
90 | ) ENGINE=MyISAM; | ||
91 | |||
92 | COMMIT; | ||
93 | |||
94 | :VERSION 2 # -------------------------- | ||
95 | |||
96 | BEGIN; | ||
97 | |||
98 | INSERT INTO `os_groups_groups` SELECT * from `diva_groups_groups`; | ||
99 | DROP TABLE `diva_groups_groups`; | ||
100 | INSERT INTO `os_groups_membership` SELECT * from `diva_groups_membership`; | ||
101 | DROP TABLE `diva_groups_membership`; | ||
102 | INSERT INTO `os_groups_roles` SELECT * from `diva_groups_roles`; | ||
103 | DROP TABLE `diva_groups_roles`; | ||
104 | INSERT INTO `os_groups_rolemembership` SELECT * from `diva_groups_rolemembership`; | ||
105 | DROP TABLE `diva_groups_rolemembership`; | ||
106 | INSERT INTO `os_groups_invites` SELECT * from `diva_groups_invites`; | ||
107 | DROP TABLE `diva_groups_invites`; | ||
108 | INSERT INTO `os_groups_notices` SELECT * from `diva_groups_notices`; | ||
109 | DROP TABLE `diva_groups_notices`; | ||
110 | INSERT INTO `os_groups_principals` SELECT * from `diva_groups_principals`; | ||
111 | DROP TABLE `diva_groups_principals`; | ||
112 | |||
113 | DELETE FROM `migrations` WHERE name='diva_im_Store'; | ||
114 | |||
115 | COMMIT; \ No newline at end of file | ||