diff options
Diffstat (limited to 'OpenSim/Data/MySQL')
46 files changed, 10392 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs new file mode 100644 index 0000000..17f1374 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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..8569c90 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | public override void Initialise() | ||
83 | { | ||
84 | throw new NotImplementedException(); | ||
85 | } | ||
86 | |||
87 | public override void Dispose() { } | ||
88 | |||
89 | /// <summary> | ||
90 | /// The name of this DB provider | ||
91 | /// </summary> | ||
92 | override public string Name | ||
93 | { | ||
94 | get { return "MySQL Asset storage engine"; } | ||
95 | } | ||
96 | |||
97 | #endregion | ||
98 | |||
99 | #region IAssetDataPlugin Members | ||
100 | |||
101 | /// <summary> | ||
102 | /// Fetch Asset <paramref name="assetID"/> from database | ||
103 | /// </summary> | ||
104 | /// <param name="assetID">Asset UUID to fetch</param> | ||
105 | /// <returns>Return the asset</returns> | ||
106 | /// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks> | ||
107 | override public AssetBase GetAsset(UUID assetID) | ||
108 | { | ||
109 | AssetBase asset = null; | ||
110 | |||
111 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
112 | { | ||
113 | dbcon.Open(); | ||
114 | |||
115 | using (MySqlCommand cmd = new MySqlCommand( | ||
116 | "SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id", | ||
117 | dbcon)) | ||
118 | { | ||
119 | cmd.Parameters.AddWithValue("?id", assetID.ToString()); | ||
120 | |||
121 | try | ||
122 | { | ||
123 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
124 | { | ||
125 | if (dbReader.Read()) | ||
126 | { | ||
127 | asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString()); | ||
128 | asset.Data = (byte[])dbReader["data"]; | ||
129 | asset.Description = (string)dbReader["description"]; | ||
130 | |||
131 | string local = dbReader["local"].ToString(); | ||
132 | if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) | ||
133 | asset.Local = true; | ||
134 | else | ||
135 | asset.Local = false; | ||
136 | |||
137 | asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); | ||
138 | asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | catch (Exception e) | ||
143 | { | ||
144 | m_log.Error( | ||
145 | string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e); | ||
146 | } | ||
147 | } | ||
148 | dbcon.Close(); | ||
149 | } | ||
150 | |||
151 | return asset; | ||
152 | } | ||
153 | |||
154 | /// <summary> | ||
155 | /// Create an asset in database, or update it if existing. | ||
156 | /// </summary> | ||
157 | /// <param name="asset">Asset UUID to create</param> | ||
158 | /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> | ||
159 | override public bool StoreAsset(AssetBase asset) | ||
160 | { | ||
161 | string assetName = asset.Name; | ||
162 | if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) | ||
163 | { | ||
164 | assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); | ||
165 | m_log.WarnFormat( | ||
166 | "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
167 | asset.Name, asset.ID, asset.Name.Length, assetName.Length); | ||
168 | } | ||
169 | |||
170 | string assetDescription = asset.Description; | ||
171 | if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) | ||
172 | { | ||
173 | assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); | ||
174 | m_log.WarnFormat( | ||
175 | "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
176 | asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); | ||
177 | } | ||
178 | |||
179 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
180 | { | ||
181 | dbcon.Open(); | ||
182 | using (MySqlCommand cmd = | ||
183 | new MySqlCommand( | ||
184 | "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + | ||
185 | "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)", | ||
186 | dbcon)) | ||
187 | { | ||
188 | try | ||
189 | { | ||
190 | // create unix epoch time | ||
191 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
192 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
193 | cmd.Parameters.AddWithValue("?name", assetName); | ||
194 | cmd.Parameters.AddWithValue("?description", assetDescription); | ||
195 | cmd.Parameters.AddWithValue("?assetType", asset.Type); | ||
196 | cmd.Parameters.AddWithValue("?local", asset.Local); | ||
197 | cmd.Parameters.AddWithValue("?temporary", asset.Temporary); | ||
198 | cmd.Parameters.AddWithValue("?create_time", now); | ||
199 | cmd.Parameters.AddWithValue("?access_time", now); | ||
200 | cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); | ||
201 | cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); | ||
202 | cmd.Parameters.AddWithValue("?data", asset.Data); | ||
203 | cmd.ExecuteNonQuery(); | ||
204 | dbcon.Close(); | ||
205 | return true; | ||
206 | } | ||
207 | catch (Exception e) | ||
208 | { | ||
209 | m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", | ||
210 | asset.FullID, asset.Name, e.Message); | ||
211 | dbcon.Close(); | ||
212 | return false; | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | private void UpdateAccessTime(AssetBase asset) | ||
219 | { | ||
220 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
221 | { | ||
222 | dbcon.Open(); | ||
223 | |||
224 | using (MySqlCommand cmd | ||
225 | = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon)) | ||
226 | { | ||
227 | try | ||
228 | { | ||
229 | // create unix epoch time | ||
230 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
231 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
232 | cmd.Parameters.AddWithValue("?access_time", now); | ||
233 | cmd.ExecuteNonQuery(); | ||
234 | } | ||
235 | catch (Exception e) | ||
236 | { | ||
237 | m_log.Error( | ||
238 | string.Format( | ||
239 | "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ", | ||
240 | asset.FullID, asset.Name), | ||
241 | e); | ||
242 | } | ||
243 | } | ||
244 | dbcon.Close(); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /// <summary> | ||
249 | /// Check if the assets exist in the database. | ||
250 | /// </summary> | ||
251 | /// <param name="uuidss">The assets' IDs</param> | ||
252 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
253 | public override bool[] AssetsExist(UUID[] uuids) | ||
254 | { | ||
255 | if (uuids.Length == 0) | ||
256 | return new bool[0]; | ||
257 | |||
258 | HashSet<UUID> exist = new HashSet<UUID>(); | ||
259 | |||
260 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
261 | string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids); | ||
262 | |||
263 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
264 | { | ||
265 | dbcon.Open(); | ||
266 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
267 | { | ||
268 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
269 | { | ||
270 | while (dbReader.Read()) | ||
271 | { | ||
272 | UUID id = DBGuid.FromDB(dbReader["id"]); | ||
273 | exist.Add(id); | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | dbcon.Close(); | ||
278 | } | ||
279 | |||
280 | bool[] results = new bool[uuids.Length]; | ||
281 | for (int i = 0; i < uuids.Length; i++) | ||
282 | results[i] = exist.Contains(uuids[i]); | ||
283 | |||
284 | return results; | ||
285 | } | ||
286 | |||
287 | /// <summary> | ||
288 | /// Returns a list of AssetMetadata objects. The list is a subset of | ||
289 | /// the entire data set offset by <paramref name="start" /> containing | ||
290 | /// <paramref name="count" /> elements. | ||
291 | /// </summary> | ||
292 | /// <param name="start">The number of results to discard from the total data set.</param> | ||
293 | /// <param name="count">The number of rows the returned list should contain.</param> | ||
294 | /// <returns>A list of AssetMetadata objects.</returns> | ||
295 | public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count) | ||
296 | { | ||
297 | List<AssetMetadata> retList = new List<AssetMetadata>(count); | ||
298 | |||
299 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
300 | { | ||
301 | dbcon.Open(); | ||
302 | |||
303 | using (MySqlCommand cmd | ||
304 | = new MySqlCommand( | ||
305 | "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", | ||
306 | dbcon)) | ||
307 | { | ||
308 | cmd.Parameters.AddWithValue("?start", start); | ||
309 | cmd.Parameters.AddWithValue("?count", count); | ||
310 | |||
311 | try | ||
312 | { | ||
313 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
314 | { | ||
315 | while (dbReader.Read()) | ||
316 | { | ||
317 | AssetMetadata metadata = new AssetMetadata(); | ||
318 | metadata.Name = (string)dbReader["name"]; | ||
319 | metadata.Description = (string)dbReader["description"]; | ||
320 | metadata.Type = (sbyte)dbReader["assetType"]; | ||
321 | metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. | ||
322 | metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | ||
323 | metadata.FullID = DBGuid.FromDB(dbReader["id"]); | ||
324 | metadata.CreatorID = dbReader["CreatorID"].ToString(); | ||
325 | |||
326 | // Current SHA1s are not stored/computed. | ||
327 | metadata.SHA1 = new byte[] { }; | ||
328 | |||
329 | retList.Add(metadata); | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | catch (Exception e) | ||
334 | { | ||
335 | m_log.Error( | ||
336 | string.Format( | ||
337 | "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ", | ||
338 | start, count), | ||
339 | e); | ||
340 | } | ||
341 | } | ||
342 | dbcon.Close(); | ||
343 | } | ||
344 | |||
345 | return retList; | ||
346 | } | ||
347 | |||
348 | public override bool Delete(string id) | ||
349 | { | ||
350 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
351 | { | ||
352 | dbcon.Open(); | ||
353 | |||
354 | using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon)) | ||
355 | { | ||
356 | cmd.Parameters.AddWithValue("?id", id); | ||
357 | cmd.ExecuteNonQuery(); | ||
358 | } | ||
359 | dbcon.Close(); | ||
360 | } | ||
361 | |||
362 | return true; | ||
363 | } | ||
364 | |||
365 | #endregion | ||
366 | } | ||
367 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs new file mode 100644 index 0000000..fef582e --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs | |||
@@ -0,0 +1,231 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | public AuthenticationData Get(UUID principalID) | ||
67 | { | ||
68 | AuthenticationData ret = new AuthenticationData(); | ||
69 | ret.Data = new Dictionary<string, object>(); | ||
70 | |||
71 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
72 | { | ||
73 | dbcon.Open(); | ||
74 | |||
75 | using (MySqlCommand cmd | ||
76 | = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon)) | ||
77 | { | ||
78 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
79 | |||
80 | using(IDataReader result = cmd.ExecuteReader()) | ||
81 | { | ||
82 | if(result.Read()) | ||
83 | { | ||
84 | ret.PrincipalID = principalID; | ||
85 | |||
86 | CheckColumnNames(result); | ||
87 | |||
88 | foreach(string s in m_ColumnNames) | ||
89 | { | ||
90 | if(s == "UUID") | ||
91 | continue; | ||
92 | |||
93 | ret.Data[s] = result[s].ToString(); | ||
94 | } | ||
95 | |||
96 | dbcon.Close(); | ||
97 | return ret; | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | dbcon.Close(); | ||
102 | return null; | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | private void CheckColumnNames(IDataReader result) | ||
110 | { | ||
111 | if (m_ColumnNames != null) | ||
112 | return; | ||
113 | |||
114 | List<string> columnNames = new List<string>(); | ||
115 | |||
116 | DataTable schemaTable = result.GetSchemaTable(); | ||
117 | foreach (DataRow row in schemaTable.Rows) | ||
118 | columnNames.Add(row["ColumnName"].ToString()); | ||
119 | |||
120 | m_ColumnNames = columnNames; | ||
121 | } | ||
122 | |||
123 | public bool Store(AuthenticationData data) | ||
124 | { | ||
125 | if (data.Data.ContainsKey("UUID")) | ||
126 | data.Data.Remove("UUID"); | ||
127 | |||
128 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
129 | |||
130 | using (MySqlCommand cmd = new MySqlCommand()) | ||
131 | { | ||
132 | string update = "update `"+m_Realm+"` set "; | ||
133 | bool first = true; | ||
134 | foreach (string field in fields) | ||
135 | { | ||
136 | if (!first) | ||
137 | update += ", "; | ||
138 | update += "`" + field + "` = ?"+field; | ||
139 | |||
140 | first = false; | ||
141 | |||
142 | cmd.Parameters.AddWithValue("?"+field, data.Data[field]); | ||
143 | } | ||
144 | |||
145 | update += " where UUID = ?principalID"; | ||
146 | |||
147 | cmd.CommandText = update; | ||
148 | cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); | ||
149 | |||
150 | if (ExecuteNonQuery(cmd) < 1) | ||
151 | { | ||
152 | string insert = "insert into `" + m_Realm + "` (`UUID`, `" + | ||
153 | String.Join("`, `", fields) + | ||
154 | "`) values (?principalID, ?" + String.Join(", ?", fields) + ")"; | ||
155 | |||
156 | cmd.CommandText = insert; | ||
157 | |||
158 | if (ExecuteNonQuery(cmd) < 1) | ||
159 | return false; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return true; | ||
164 | } | ||
165 | |||
166 | public bool SetDataItem(UUID principalID, string item, string value) | ||
167 | { | ||
168 | using (MySqlCommand cmd | ||
169 | = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID")) | ||
170 | { | ||
171 | cmd.Parameters.AddWithValue("?"+item, value); | ||
172 | cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); | ||
173 | |||
174 | if (ExecuteNonQuery(cmd) > 0) | ||
175 | return true; | ||
176 | } | ||
177 | |||
178 | return false; | ||
179 | } | ||
180 | |||
181 | public bool SetToken(UUID principalID, string token, int lifetime) | ||
182 | { | ||
183 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
184 | DoExpire(); | ||
185 | |||
186 | using (MySqlCommand cmd | ||
187 | = new MySqlCommand( | ||
188 | "insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))")) | ||
189 | { | ||
190 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
191 | cmd.Parameters.AddWithValue("?token", token); | ||
192 | cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); | ||
193 | |||
194 | if (ExecuteNonQuery(cmd) > 0) | ||
195 | return true; | ||
196 | } | ||
197 | |||
198 | return false; | ||
199 | } | ||
200 | |||
201 | public bool CheckToken(UUID principalID, string token, int lifetime) | ||
202 | { | ||
203 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
204 | DoExpire(); | ||
205 | |||
206 | using (MySqlCommand cmd | ||
207 | = new MySqlCommand( | ||
208 | "update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()")) | ||
209 | { | ||
210 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
211 | cmd.Parameters.AddWithValue("?token", token); | ||
212 | cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); | ||
213 | |||
214 | if (ExecuteNonQuery(cmd) > 0) | ||
215 | return true; | ||
216 | } | ||
217 | |||
218 | return false; | ||
219 | } | ||
220 | |||
221 | private void DoExpire() | ||
222 | { | ||
223 | using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()")) | ||
224 | { | ||
225 | ExecuteNonQuery(cmd); | ||
226 | } | ||
227 | |||
228 | m_LastExpire = System.Environment.TickCount; | ||
229 | } | ||
230 | } | ||
231 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLAvatarData.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs new file mode 100644 index 0000000..63e8020 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLAvatarData.cs | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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..eeedf02 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs | |||
@@ -0,0 +1,600 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
86 | |||
87 | Type t = typeof(EstateSettings); | ||
88 | m_Fields = t.GetFields(BindingFlags.NonPublic | | ||
89 | BindingFlags.Instance | | ||
90 | BindingFlags.DeclaredOnly); | ||
91 | |||
92 | foreach (FieldInfo f in m_Fields) | ||
93 | { | ||
94 | if (f.Name.Substring(0, 2) == "m_") | ||
95 | m_FieldMap[f.Name.Substring(2)] = f; | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | |||
100 | private string[] FieldList | ||
101 | { | ||
102 | get { return new List<string>(m_FieldMap.Keys).ToArray(); } | ||
103 | } | ||
104 | |||
105 | public EstateSettings LoadEstateSettings(UUID regionID, bool create) | ||
106 | { | ||
107 | string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + | ||
108 | " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID"; | ||
109 | |||
110 | using (MySqlCommand cmd = new MySqlCommand()) | ||
111 | { | ||
112 | cmd.CommandText = sql; | ||
113 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
114 | |||
115 | EstateSettings e = DoLoad(cmd, regionID, create); | ||
116 | if (!create && e.EstateID == 0) // Not found | ||
117 | return null; | ||
118 | |||
119 | return e; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | public EstateSettings CreateNewEstate() | ||
124 | { | ||
125 | EstateSettings es = new EstateSettings(); | ||
126 | es.OnSave += StoreEstateSettings; | ||
127 | |||
128 | DoCreate(es); | ||
129 | |||
130 | LoadBanList(es); | ||
131 | |||
132 | es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); | ||
133 | es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); | ||
134 | es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); | ||
135 | |||
136 | return es; | ||
137 | } | ||
138 | |||
139 | private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create) | ||
140 | { | ||
141 | EstateSettings es = new EstateSettings(); | ||
142 | es.OnSave += StoreEstateSettings; | ||
143 | |||
144 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
145 | { | ||
146 | dbcon.Open(); | ||
147 | cmd.Connection = dbcon; | ||
148 | |||
149 | bool found = false; | ||
150 | |||
151 | using (IDataReader r = cmd.ExecuteReader()) | ||
152 | { | ||
153 | if (r.Read()) | ||
154 | { | ||
155 | found = true; | ||
156 | |||
157 | foreach (string name in FieldList) | ||
158 | { | ||
159 | if (m_FieldMap[name].FieldType == typeof(bool)) | ||
160 | { | ||
161 | m_FieldMap[name].SetValue(es, Convert.ToInt32(r[name]) != 0); | ||
162 | } | ||
163 | else if (m_FieldMap[name].FieldType == typeof(UUID)) | ||
164 | { | ||
165 | m_FieldMap[name].SetValue(es, DBGuid.FromDB(r[name])); | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | m_FieldMap[name].SetValue(es, r[name]); | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | dbcon.Close(); | ||
175 | cmd.Connection = null; | ||
176 | |||
177 | if (!found && create) | ||
178 | { | ||
179 | DoCreate(es); | ||
180 | LinkRegion(regionID, (int)es.EstateID); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | LoadBanList(es); | ||
185 | es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); | ||
186 | es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); | ||
187 | es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); | ||
188 | return es; | ||
189 | } | ||
190 | |||
191 | private void DoCreate(EstateSettings es) | ||
192 | { | ||
193 | // Migration case | ||
194 | List<string> names = new List<string>(FieldList); | ||
195 | |||
196 | names.Remove("EstateID"); | ||
197 | |||
198 | string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; | ||
199 | |||
200 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
201 | { | ||
202 | dbcon.Open(); | ||
203 | using (MySqlCommand cmd2 = dbcon.CreateCommand()) | ||
204 | { | ||
205 | cmd2.CommandText = sql; | ||
206 | cmd2.Parameters.Clear(); | ||
207 | |||
208 | foreach (string name in FieldList) | ||
209 | { | ||
210 | if (m_FieldMap[name].GetValue(es) is bool) | ||
211 | { | ||
212 | if ((bool)m_FieldMap[name].GetValue(es)) | ||
213 | cmd2.Parameters.AddWithValue("?" + name, "1"); | ||
214 | else | ||
215 | cmd2.Parameters.AddWithValue("?" + name, "0"); | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | cmd2.ExecuteNonQuery(); | ||
224 | |||
225 | cmd2.CommandText = "select LAST_INSERT_ID() as id"; | ||
226 | cmd2.Parameters.Clear(); | ||
227 | |||
228 | using (IDataReader r = cmd2.ExecuteReader()) | ||
229 | { | ||
230 | r.Read(); | ||
231 | es.EstateID = Convert.ToUInt32(r["id"]); | ||
232 | } | ||
233 | |||
234 | es.Save(); | ||
235 | } | ||
236 | dbcon.Close(); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | public void StoreEstateSettings(EstateSettings es) | ||
241 | { | ||
242 | string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")"; | ||
243 | |||
244 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
245 | { | ||
246 | dbcon.Open(); | ||
247 | |||
248 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
249 | { | ||
250 | cmd.CommandText = sql; | ||
251 | |||
252 | foreach (string name in FieldList) | ||
253 | { | ||
254 | if (m_FieldMap[name].GetValue(es) is bool) | ||
255 | { | ||
256 | if ((bool)m_FieldMap[name].GetValue(es)) | ||
257 | cmd.Parameters.AddWithValue("?" + name, "1"); | ||
258 | else | ||
259 | cmd.Parameters.AddWithValue("?" + name, "0"); | ||
260 | } | ||
261 | else | ||
262 | { | ||
263 | cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | cmd.ExecuteNonQuery(); | ||
268 | } | ||
269 | dbcon.Close(); | ||
270 | } | ||
271 | |||
272 | SaveBanList(es); | ||
273 | SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); | ||
274 | SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess); | ||
275 | SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups); | ||
276 | } | ||
277 | |||
278 | private void LoadBanList(EstateSettings es) | ||
279 | { | ||
280 | es.ClearBans(); | ||
281 | |||
282 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
283 | { | ||
284 | dbcon.Open(); | ||
285 | |||
286 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
287 | { | ||
288 | cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID"; | ||
289 | cmd.Parameters.AddWithValue("?EstateID", es.EstateID); | ||
290 | |||
291 | using (IDataReader r = cmd.ExecuteReader()) | ||
292 | { | ||
293 | while (r.Read()) | ||
294 | { | ||
295 | EstateBan eb = new EstateBan(); | ||
296 | |||
297 | UUID uuid = new UUID(); | ||
298 | UUID.TryParse(r["bannedUUID"].ToString(), out uuid); | ||
299 | |||
300 | eb.BannedUserID = uuid; | ||
301 | eb.BannedHostAddress = "0.0.0.0"; | ||
302 | eb.BannedHostIPMask = "0.0.0.0"; | ||
303 | es.AddBan(eb); | ||
304 | } | ||
305 | } | ||
306 | } | ||
307 | dbcon.Close(); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | private void SaveBanList(EstateSettings es) | ||
312 | { | ||
313 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
314 | { | ||
315 | dbcon.Open(); | ||
316 | |||
317 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
318 | { | ||
319 | cmd.CommandText = "delete from estateban where EstateID = ?EstateID"; | ||
320 | cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); | ||
321 | |||
322 | cmd.ExecuteNonQuery(); | ||
323 | |||
324 | cmd.Parameters.Clear(); | ||
325 | |||
326 | cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )"; | ||
327 | |||
328 | foreach (EstateBan b in es.EstateBans) | ||
329 | { | ||
330 | cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); | ||
331 | cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString()); | ||
332 | |||
333 | cmd.ExecuteNonQuery(); | ||
334 | cmd.Parameters.Clear(); | ||
335 | } | ||
336 | } | ||
337 | dbcon.Close(); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | void SaveUUIDList(uint EstateID, string table, UUID[] data) | ||
342 | { | ||
343 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
344 | { | ||
345 | dbcon.Open(); | ||
346 | |||
347 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
348 | { | ||
349 | cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID"; | ||
350 | cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); | ||
351 | |||
352 | cmd.ExecuteNonQuery(); | ||
353 | |||
354 | cmd.Parameters.Clear(); | ||
355 | |||
356 | cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )"; | ||
357 | |||
358 | foreach (UUID uuid in data) | ||
359 | { | ||
360 | cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); | ||
361 | cmd.Parameters.AddWithValue("?uuid", uuid.ToString()); | ||
362 | |||
363 | cmd.ExecuteNonQuery(); | ||
364 | cmd.Parameters.Clear(); | ||
365 | } | ||
366 | } | ||
367 | dbcon.Close(); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | UUID[] LoadUUIDList(uint EstateID, string table) | ||
372 | { | ||
373 | List<UUID> uuids = new List<UUID>(); | ||
374 | |||
375 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
376 | { | ||
377 | dbcon.Open(); | ||
378 | |||
379 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
380 | { | ||
381 | cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID"; | ||
382 | cmd.Parameters.AddWithValue("?EstateID", EstateID); | ||
383 | |||
384 | using (IDataReader r = cmd.ExecuteReader()) | ||
385 | { | ||
386 | while (r.Read()) | ||
387 | { | ||
388 | // EstateBan eb = new EstateBan(); | ||
389 | uuids.Add(DBGuid.FromDB(r["uuid"])); | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | dbcon.Close(); | ||
394 | } | ||
395 | |||
396 | return uuids.ToArray(); | ||
397 | } | ||
398 | |||
399 | public EstateSettings LoadEstateSettings(int estateID) | ||
400 | { | ||
401 | using (MySqlCommand cmd = new MySqlCommand()) | ||
402 | { | ||
403 | string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = ?EstateID"; | ||
404 | |||
405 | cmd.CommandText = sql; | ||
406 | cmd.Parameters.AddWithValue("?EstateID", estateID); | ||
407 | |||
408 | EstateSettings e = DoLoad(cmd, UUID.Zero, false); | ||
409 | if (e.EstateID != estateID) | ||
410 | return null; | ||
411 | return e; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | public List<EstateSettings> LoadEstateSettingsAll() | ||
416 | { | ||
417 | List<EstateSettings> allEstateSettings = new List<EstateSettings>(); | ||
418 | |||
419 | List<int> allEstateIds = GetEstatesAll(); | ||
420 | |||
421 | foreach (int estateId in allEstateIds) | ||
422 | allEstateSettings.Add(LoadEstateSettings(estateId)); | ||
423 | |||
424 | return allEstateSettings; | ||
425 | } | ||
426 | |||
427 | public List<int> GetEstatesAll() | ||
428 | { | ||
429 | List<int> result = new List<int>(); | ||
430 | |||
431 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
432 | { | ||
433 | dbcon.Open(); | ||
434 | |||
435 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
436 | { | ||
437 | cmd.CommandText = "select estateID from estate_settings"; | ||
438 | |||
439 | using (IDataReader reader = cmd.ExecuteReader()) | ||
440 | { | ||
441 | while (reader.Read()) | ||
442 | { | ||
443 | result.Add(Convert.ToInt32(reader["EstateID"])); | ||
444 | } | ||
445 | reader.Close(); | ||
446 | } | ||
447 | } | ||
448 | dbcon.Close(); | ||
449 | } | ||
450 | |||
451 | return result; | ||
452 | } | ||
453 | |||
454 | public List<int> GetEstates(string search) | ||
455 | { | ||
456 | List<int> result = new List<int>(); | ||
457 | |||
458 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
459 | { | ||
460 | dbcon.Open(); | ||
461 | |||
462 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
463 | { | ||
464 | cmd.CommandText = "select estateID from estate_settings where EstateName = ?EstateName"; | ||
465 | cmd.Parameters.AddWithValue("?EstateName", search); | ||
466 | |||
467 | using (IDataReader reader = cmd.ExecuteReader()) | ||
468 | { | ||
469 | while (reader.Read()) | ||
470 | { | ||
471 | result.Add(Convert.ToInt32(reader["EstateID"])); | ||
472 | } | ||
473 | reader.Close(); | ||
474 | } | ||
475 | } | ||
476 | dbcon.Close(); | ||
477 | } | ||
478 | |||
479 | return result; | ||
480 | } | ||
481 | |||
482 | public List<int> GetEstatesByOwner(UUID ownerID) | ||
483 | { | ||
484 | List<int> result = new List<int>(); | ||
485 | |||
486 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
487 | { | ||
488 | dbcon.Open(); | ||
489 | |||
490 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
491 | { | ||
492 | cmd.CommandText = "select estateID from estate_settings where EstateOwner = ?EstateOwner"; | ||
493 | cmd.Parameters.AddWithValue("?EstateOwner", ownerID); | ||
494 | |||
495 | using (IDataReader reader = cmd.ExecuteReader()) | ||
496 | { | ||
497 | while (reader.Read()) | ||
498 | { | ||
499 | result.Add(Convert.ToInt32(reader["EstateID"])); | ||
500 | } | ||
501 | reader.Close(); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | dbcon.Close(); | ||
506 | } | ||
507 | |||
508 | return result; | ||
509 | } | ||
510 | |||
511 | public bool LinkRegion(UUID regionID, int estateID) | ||
512 | { | ||
513 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
514 | { | ||
515 | dbcon.Open(); | ||
516 | MySqlTransaction transaction = dbcon.BeginTransaction(); | ||
517 | |||
518 | try | ||
519 | { | ||
520 | // Delete any existing association of this region with an estate. | ||
521 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
522 | { | ||
523 | cmd.Transaction = transaction; | ||
524 | cmd.CommandText = "delete from estate_map where RegionID = ?RegionID"; | ||
525 | cmd.Parameters.AddWithValue("?RegionID", regionID); | ||
526 | |||
527 | cmd.ExecuteNonQuery(); | ||
528 | } | ||
529 | |||
530 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
531 | { | ||
532 | cmd.Transaction = transaction; | ||
533 | cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; | ||
534 | cmd.Parameters.AddWithValue("?RegionID", regionID); | ||
535 | cmd.Parameters.AddWithValue("?EstateID", estateID); | ||
536 | |||
537 | int ret = cmd.ExecuteNonQuery(); | ||
538 | |||
539 | if (ret != 0) | ||
540 | transaction.Commit(); | ||
541 | else | ||
542 | transaction.Rollback(); | ||
543 | |||
544 | dbcon.Close(); | ||
545 | |||
546 | return (ret != 0); | ||
547 | } | ||
548 | } | ||
549 | catch (MySqlException ex) | ||
550 | { | ||
551 | m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message); | ||
552 | transaction.Rollback(); | ||
553 | } | ||
554 | |||
555 | dbcon.Close(); | ||
556 | } | ||
557 | |||
558 | return false; | ||
559 | } | ||
560 | |||
561 | public List<UUID> GetRegions(int estateID) | ||
562 | { | ||
563 | List<UUID> result = new List<UUID>(); | ||
564 | |||
565 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
566 | { | ||
567 | dbcon.Open(); | ||
568 | |||
569 | try | ||
570 | { | ||
571 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
572 | { | ||
573 | cmd.CommandText = "select RegionID from estate_map where EstateID = ?EstateID"; | ||
574 | cmd.Parameters.AddWithValue("?EstateID", estateID.ToString()); | ||
575 | |||
576 | using (IDataReader reader = cmd.ExecuteReader()) | ||
577 | { | ||
578 | while(reader.Read()) | ||
579 | result.Add(DBGuid.FromDB(reader["RegionID"])); | ||
580 | reader.Close(); | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | catch (Exception e) | ||
585 | { | ||
586 | m_log.Error("[REGION DB]: Error reading estate map. " + e.ToString()); | ||
587 | return result; | ||
588 | } | ||
589 | dbcon.Close(); | ||
590 | } | ||
591 | |||
592 | return result; | ||
593 | } | ||
594 | |||
595 | public bool DeleteEstate(int estateID) | ||
596 | { | ||
597 | return false; | ||
598 | } | ||
599 | } | ||
600 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs new file mode 100644 index 0000000..6c48607 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs | |||
@@ -0,0 +1,433 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 string m_ConnectionString; | ||
45 | protected string m_Table; | ||
46 | |||
47 | /// <summary> | ||
48 | /// Number of days that must pass before we update the access time on an asset when it has been fetched | ||
49 | /// Config option to change this is "DaysBetweenAccessTimeUpdates" | ||
50 | /// </summary> | ||
51 | private int DaysBetweenAccessTimeUpdates = 0; | ||
52 | |||
53 | protected virtual Assembly Assembly | ||
54 | { | ||
55 | get { return GetType().Assembly; } | ||
56 | } | ||
57 | |||
58 | public MySQLFSAssetData() | ||
59 | { | ||
60 | } | ||
61 | |||
62 | #region IPlugin Members | ||
63 | |||
64 | public string Version { get { return "1.0.0.0"; } } | ||
65 | |||
66 | // Loads and initialises the MySQL storage plugin and checks for migrations | ||
67 | public void Initialise(string connect, string realm, int UpdateAccessTime) | ||
68 | { | ||
69 | m_ConnectionString = connect; | ||
70 | m_Table = realm; | ||
71 | |||
72 | DaysBetweenAccessTimeUpdates = UpdateAccessTime; | ||
73 | |||
74 | try | ||
75 | { | ||
76 | using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) | ||
77 | { | ||
78 | conn.Open(); | ||
79 | Migration m = new Migration(conn, Assembly, "FSAssetStore"); | ||
80 | m.Update(); | ||
81 | conn.Close(); | ||
82 | } | ||
83 | } | ||
84 | catch (MySqlException e) | ||
85 | { | ||
86 | m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", e.Message.ToString()); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | public void Initialise() | ||
91 | { | ||
92 | throw new NotImplementedException(); | ||
93 | } | ||
94 | |||
95 | public void Dispose() { } | ||
96 | |||
97 | public string Name | ||
98 | { | ||
99 | get { return "MySQL FSAsset storage engine"; } | ||
100 | } | ||
101 | |||
102 | #endregion | ||
103 | |||
104 | private bool ExecuteNonQuery(MySqlCommand cmd) | ||
105 | { | ||
106 | using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) | ||
107 | { | ||
108 | try | ||
109 | { | ||
110 | conn.Open(); | ||
111 | } | ||
112 | catch (MySqlException e) | ||
113 | { | ||
114 | m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString()); | ||
115 | return false; | ||
116 | } | ||
117 | |||
118 | cmd.Connection = conn; | ||
119 | try | ||
120 | { | ||
121 | cmd.ExecuteNonQuery(); | ||
122 | } | ||
123 | catch (MySqlException e) | ||
124 | { | ||
125 | cmd.Connection = null; | ||
126 | conn.Close(); | ||
127 | m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString()); | ||
128 | return false; | ||
129 | } | ||
130 | conn.Close(); | ||
131 | cmd.Connection = null; | ||
132 | } | ||
133 | |||
134 | return true; | ||
135 | } | ||
136 | |||
137 | #region IFSAssetDataPlugin Members | ||
138 | |||
139 | public AssetMetadata Get(string id, out string hash) | ||
140 | { | ||
141 | hash = String.Empty; | ||
142 | |||
143 | AssetMetadata meta = new AssetMetadata(); | ||
144 | |||
145 | using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) | ||
146 | { | ||
147 | try | ||
148 | { | ||
149 | conn.Open(); | ||
150 | } | ||
151 | catch (MySqlException e) | ||
152 | { | ||
153 | m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString()); | ||
154 | return null; | ||
155 | } | ||
156 | |||
157 | using (MySqlCommand cmd = conn.CreateCommand()) | ||
158 | { | ||
159 | cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, asset_flags, access_time from {0} where id = ?id", m_Table); | ||
160 | cmd.Parameters.AddWithValue("?id", id); | ||
161 | |||
162 | using (IDataReader reader = cmd.ExecuteReader()) | ||
163 | { | ||
164 | if (!reader.Read()) | ||
165 | return null; | ||
166 | |||
167 | hash = reader["hash"].ToString(); | ||
168 | |||
169 | meta.ID = id; | ||
170 | meta.FullID = new UUID(id); | ||
171 | |||
172 | meta.Name = reader["name"].ToString(); | ||
173 | meta.Description = reader["description"].ToString(); | ||
174 | meta.Type = (sbyte)Convert.ToInt32(reader["type"]); | ||
175 | meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); | ||
176 | meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); | ||
177 | meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]); | ||
178 | |||
179 | int AccessTime = Convert.ToInt32(reader["access_time"]); | ||
180 | UpdateAccessTime(id, AccessTime); | ||
181 | } | ||
182 | } | ||
183 | conn.Close(); | ||
184 | } | ||
185 | |||
186 | return meta; | ||
187 | } | ||
188 | |||
189 | private void UpdateAccessTime(string AssetID, int AccessTime) | ||
190 | { | ||
191 | // Reduce DB work by only updating access time if asset hasn't recently been accessed | ||
192 | // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates" | ||
193 | if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates) | ||
194 | return; | ||
195 | |||
196 | using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) | ||
197 | { | ||
198 | try | ||
199 | { | ||
200 | conn.Open(); | ||
201 | } | ||
202 | catch (MySqlException e) | ||
203 | { | ||
204 | m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString()); | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | using (MySqlCommand cmd = conn.CreateCommand()) | ||
209 | { | ||
210 | cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table); | ||
211 | cmd.Parameters.AddWithValue("?id", AssetID); | ||
212 | cmd.ExecuteNonQuery(); | ||
213 | } | ||
214 | conn.Close(); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | public bool Store(AssetMetadata meta, string hash) | ||
219 | { | ||
220 | try | ||
221 | { | ||
222 | string oldhash; | ||
223 | AssetMetadata existingAsset = Get(meta.ID, out oldhash); | ||
224 | |||
225 | using (MySqlCommand cmd = new MySqlCommand()) | ||
226 | { | ||
227 | cmd.Parameters.AddWithValue("?id", meta.ID); | ||
228 | cmd.Parameters.AddWithValue("?name", meta.Name); | ||
229 | cmd.Parameters.AddWithValue("?description", meta.Description); | ||
230 | // cmd.Parameters.AddWithValue("?type", meta.Type.ToString()); | ||
231 | cmd.Parameters.AddWithValue("?type", meta.Type); | ||
232 | cmd.Parameters.AddWithValue("?hash", hash); | ||
233 | cmd.Parameters.AddWithValue("?asset_flags", meta.Flags); | ||
234 | |||
235 | if (existingAsset == null) | ||
236 | { | ||
237 | cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table); | ||
238 | |||
239 | ExecuteNonQuery(cmd); | ||
240 | |||
241 | return true; | ||
242 | } | ||
243 | |||
244 | //cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table); | ||
245 | |||
246 | //ExecuteNonQuery(cmd); | ||
247 | |||
248 | } | ||
249 | |||
250 | // return false; | ||
251 | // if the asset already exits | ||
252 | // assume it was already correctly stored | ||
253 | // or regions will keep retry. | ||
254 | return true; | ||
255 | } | ||
256 | catch(Exception e) | ||
257 | { | ||
258 | m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID); | ||
259 | m_log.Error(e.ToString()); | ||
260 | return false; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | /// <summary> | ||
265 | /// Check if the assets exist in the database. | ||
266 | /// </summary> | ||
267 | /// <param name="uuids">The asset UUID's</param> | ||
268 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
269 | public bool[] AssetsExist(UUID[] uuids) | ||
270 | { | ||
271 | if (uuids.Length == 0) | ||
272 | return new bool[0]; | ||
273 | |||
274 | bool[] results = new bool[uuids.Length]; | ||
275 | for (int i = 0; i < uuids.Length; i++) | ||
276 | results[i] = false; | ||
277 | |||
278 | HashSet<UUID> exists = new HashSet<UUID>(); | ||
279 | |||
280 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
281 | string sql = string.Format("select id from {1} where id in ({0})", ids, m_Table); | ||
282 | |||
283 | using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) | ||
284 | { | ||
285 | try | ||
286 | { | ||
287 | conn.Open(); | ||
288 | } | ||
289 | catch (MySqlException e) | ||
290 | { | ||
291 | m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString()); | ||
292 | return results; | ||
293 | } | ||
294 | |||
295 | using (MySqlCommand cmd = conn.CreateCommand()) | ||
296 | { | ||
297 | cmd.CommandText = sql; | ||
298 | |||
299 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
300 | { | ||
301 | while (dbReader.Read()) | ||
302 | { | ||
303 | UUID id = DBGuid.FromDB(dbReader["ID"]); | ||
304 | exists.Add(id); | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | conn.Close(); | ||
309 | } | ||
310 | |||
311 | for (int i = 0; i < uuids.Length; i++) | ||
312 | results[i] = exists.Contains(uuids[i]); | ||
313 | return results; | ||
314 | } | ||
315 | |||
316 | public int Count() | ||
317 | { | ||
318 | int count = 0; | ||
319 | |||
320 | using (MySqlConnection conn = new MySqlConnection(m_ConnectionString)) | ||
321 | { | ||
322 | try | ||
323 | { | ||
324 | conn.Open(); | ||
325 | } | ||
326 | catch (MySqlException e) | ||
327 | { | ||
328 | m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString()); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | using(MySqlCommand cmd = conn.CreateCommand()) | ||
333 | { | ||
334 | cmd.CommandText = String.Format("select count(*) as count from {0}",m_Table); | ||
335 | |||
336 | using (IDataReader reader = cmd.ExecuteReader()) | ||
337 | { | ||
338 | reader.Read(); | ||
339 | |||
340 | count = Convert.ToInt32(reader["count"]); | ||
341 | } | ||
342 | } | ||
343 | conn.Close(); | ||
344 | } | ||
345 | |||
346 | return count; | ||
347 | } | ||
348 | |||
349 | public bool Delete(string id) | ||
350 | { | ||
351 | using(MySqlCommand cmd = new MySqlCommand()) | ||
352 | { | ||
353 | |||
354 | cmd.CommandText = String.Format("delete from {0} where id = ?id",m_Table); | ||
355 | |||
356 | cmd.Parameters.AddWithValue("?id", id); | ||
357 | |||
358 | ExecuteNonQuery(cmd); | ||
359 | } | ||
360 | |||
361 | return true; | ||
362 | } | ||
363 | |||
364 | public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store) | ||
365 | { | ||
366 | int imported = 0; | ||
367 | |||
368 | using (MySqlConnection importConn = new MySqlConnection(conn)) | ||
369 | { | ||
370 | try | ||
371 | { | ||
372 | importConn.Open(); | ||
373 | } | ||
374 | catch (MySqlException e) | ||
375 | { | ||
376 | m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", | ||
377 | e.Message.ToString()); | ||
378 | |||
379 | return; | ||
380 | } | ||
381 | |||
382 | using (MySqlCommand cmd = importConn.CreateCommand()) | ||
383 | { | ||
384 | string limit = String.Empty; | ||
385 | if (count != -1) | ||
386 | { | ||
387 | limit = String.Format(" limit {0},{1}", start, count); | ||
388 | } | ||
389 | |||
390 | cmd.CommandText = String.Format("select * from {0}{1}", table, limit); | ||
391 | |||
392 | MainConsole.Instance.Output("Querying database"); | ||
393 | using (IDataReader reader = cmd.ExecuteReader()) | ||
394 | { | ||
395 | MainConsole.Instance.Output("Reading data"); | ||
396 | |||
397 | while (reader.Read()) | ||
398 | { | ||
399 | if ((imported % 100) == 0) | ||
400 | { | ||
401 | MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); | ||
402 | } | ||
403 | |||
404 | AssetBase asset = new AssetBase(); | ||
405 | AssetMetadata meta = new AssetMetadata(); | ||
406 | |||
407 | meta.ID = reader["id"].ToString(); | ||
408 | meta.FullID = new UUID(meta.ID); | ||
409 | |||
410 | meta.Name = reader["name"].ToString(); | ||
411 | meta.Description = reader["description"].ToString(); | ||
412 | meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); | ||
413 | meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); | ||
414 | meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); | ||
415 | |||
416 | asset.Metadata = meta; | ||
417 | asset.Data = (byte[])reader["data"]; | ||
418 | |||
419 | store(asset, force); | ||
420 | |||
421 | imported++; | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | importConn.Close(); | ||
426 | } | ||
427 | |||
428 | MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); | ||
429 | } | ||
430 | |||
431 | #endregion | ||
432 | } | ||
433 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs new file mode 100644 index 0000000..98106f0 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLFramework.cs | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | /// Common code for a number of database modules | ||
40 | /// </summary> | ||
41 | public class MySqlFramework | ||
42 | { | ||
43 | private static readonly log4net.ILog m_log = | ||
44 | log4net.LogManager.GetLogger( | ||
45 | System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
47 | protected string m_connectionString = String.Empty; | ||
48 | protected MySqlTransaction m_trans = null; | ||
49 | |||
50 | // Constructor using a connection string. Instances constructed | ||
51 | // this way will open a new connection for each call. | ||
52 | protected MySqlFramework(string connectionString) | ||
53 | { | ||
54 | m_connectionString = connectionString; | ||
55 | } | ||
56 | |||
57 | // Constructor using a connection object. Instances constructed | ||
58 | // this way will use the connection object and never create | ||
59 | // new connections. | ||
60 | protected MySqlFramework(MySqlTransaction trans) | ||
61 | { | ||
62 | m_trans = trans; | ||
63 | } | ||
64 | |||
65 | ////////////////////////////////////////////////////////////// | ||
66 | // | ||
67 | // All non queries are funneled through one connection | ||
68 | // to increase performance a little | ||
69 | // | ||
70 | protected int ExecuteNonQuery(MySqlCommand cmd) | ||
71 | { | ||
72 | if (m_trans == null) | ||
73 | { | ||
74 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
75 | { | ||
76 | dbcon.Open(); | ||
77 | int ret = ExecuteNonQueryWithConnection(cmd, dbcon); | ||
78 | dbcon.Close(); | ||
79 | return ret; | ||
80 | } | ||
81 | } | ||
82 | else | ||
83 | { | ||
84 | return ExecuteNonQueryWithTransaction(cmd, m_trans); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) | ||
89 | { | ||
90 | cmd.Transaction = trans; | ||
91 | return ExecuteNonQueryWithConnection(cmd, trans.Connection); | ||
92 | } | ||
93 | |||
94 | private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) | ||
95 | { | ||
96 | try | ||
97 | { | ||
98 | cmd.Connection = dbcon; | ||
99 | |||
100 | try | ||
101 | { | ||
102 | int ret = cmd.ExecuteNonQuery(); | ||
103 | cmd.Connection = null; | ||
104 | return ret; | ||
105 | } | ||
106 | catch (Exception e) | ||
107 | { | ||
108 | m_log.Error(e.Message, e); | ||
109 | m_log.Error(Environment.StackTrace.ToString()); | ||
110 | cmd.Connection = null; | ||
111 | return 0; | ||
112 | } | ||
113 | } | ||
114 | catch (Exception e) | ||
115 | { | ||
116 | m_log.Error(e.Message, e); | ||
117 | return 0; | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs new file mode 100644 index 0000000..6ba9fbd --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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..9bd3c0c --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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(MySqlTransaction trans, | ||
57 | string realm, string storeName) : base(trans) | ||
58 | { | ||
59 | m_Realm = realm; | ||
60 | |||
61 | CommonConstruct(storeName); | ||
62 | } | ||
63 | |||
64 | public MySQLGenericTableHandler(string connectionString, | ||
65 | string realm, string storeName) : base(connectionString) | ||
66 | { | ||
67 | m_Realm = realm; | ||
68 | |||
69 | CommonConstruct(storeName); | ||
70 | } | ||
71 | |||
72 | protected void CommonConstruct(string storeName) | ||
73 | { | ||
74 | if (storeName != String.Empty) | ||
75 | { | ||
76 | // We always use a new connection for any Migrations | ||
77 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
78 | { | ||
79 | dbcon.Open(); | ||
80 | Migration m = new Migration(dbcon, Assembly, storeName); | ||
81 | m.Update(); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | Type t = typeof(T); | ||
86 | FieldInfo[] fields = t.GetFields(BindingFlags.Public | | ||
87 | BindingFlags.Instance | | ||
88 | BindingFlags.DeclaredOnly); | ||
89 | |||
90 | if (fields.Length == 0) | ||
91 | return; | ||
92 | |||
93 | foreach (FieldInfo f in fields) | ||
94 | { | ||
95 | if (f.Name != "Data") | ||
96 | m_Fields[f.Name] = f; | ||
97 | else | ||
98 | m_DataField = f; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | private void CheckColumnNames(IDataReader reader) | ||
103 | { | ||
104 | if (m_ColumnNames != null) | ||
105 | return; | ||
106 | |||
107 | List<string> columnNames = new List<string>(); | ||
108 | |||
109 | DataTable schemaTable = reader.GetSchemaTable(); | ||
110 | foreach (DataRow row in schemaTable.Rows) | ||
111 | { | ||
112 | if (row["ColumnName"] != null && | ||
113 | (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) | ||
114 | columnNames.Add(row["ColumnName"].ToString()); | ||
115 | } | ||
116 | |||
117 | m_ColumnNames = columnNames; | ||
118 | } | ||
119 | |||
120 | public virtual T[] Get(string field, string key) | ||
121 | { | ||
122 | return Get(new string[] { field }, new string[] { key }); | ||
123 | } | ||
124 | |||
125 | public virtual T[] Get(string[] fields, string[] keys) | ||
126 | { | ||
127 | return Get(fields, keys, String.Empty); | ||
128 | } | ||
129 | |||
130 | public virtual T[] Get(string[] fields, string[] keys, string options) | ||
131 | { | ||
132 | if (fields.Length != keys.Length) | ||
133 | return new T[0]; | ||
134 | |||
135 | List<string> terms = new List<string>(); | ||
136 | |||
137 | using (MySqlCommand cmd = new MySqlCommand()) | ||
138 | { | ||
139 | for (int i = 0 ; i < fields.Length ; i++) | ||
140 | { | ||
141 | cmd.Parameters.AddWithValue(fields[i], keys[i]); | ||
142 | terms.Add("`" + fields[i] + "` = ?" + fields[i]); | ||
143 | } | ||
144 | |||
145 | string where = String.Join(" and ", terms.ToArray()); | ||
146 | |||
147 | string query = String.Format("select * from {0} where {1} {2}", | ||
148 | m_Realm, where, options); | ||
149 | |||
150 | cmd.CommandText = query; | ||
151 | |||
152 | return DoQuery(cmd); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | protected T[] DoQuery(MySqlCommand cmd) | ||
157 | { | ||
158 | if (m_trans == null) | ||
159 | { | ||
160 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
161 | { | ||
162 | dbcon.Open(); | ||
163 | T[] ret = DoQueryWithConnection(cmd, dbcon); | ||
164 | dbcon.Close(); | ||
165 | return ret; | ||
166 | } | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | return DoQueryWithTransaction(cmd, m_trans); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) | ||
175 | { | ||
176 | cmd.Transaction = trans; | ||
177 | |||
178 | return DoQueryWithConnection(cmd, trans.Connection); | ||
179 | } | ||
180 | |||
181 | protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) | ||
182 | { | ||
183 | List<T> result = new List<T>(); | ||
184 | |||
185 | cmd.Connection = dbcon; | ||
186 | |||
187 | using (IDataReader reader = cmd.ExecuteReader()) | ||
188 | { | ||
189 | if (reader == null) | ||
190 | return new T[0]; | ||
191 | |||
192 | CheckColumnNames(reader); | ||
193 | |||
194 | while (reader.Read()) | ||
195 | { | ||
196 | T row = new T(); | ||
197 | |||
198 | foreach (string name in m_Fields.Keys) | ||
199 | { | ||
200 | if (reader[name] is DBNull) | ||
201 | { | ||
202 | continue; | ||
203 | } | ||
204 | if (m_Fields[name].FieldType == typeof(bool)) | ||
205 | { | ||
206 | int v = Convert.ToInt32(reader[name]); | ||
207 | m_Fields[name].SetValue(row, v != 0 ? true : false); | ||
208 | } | ||
209 | else if (m_Fields[name].FieldType == typeof(UUID)) | ||
210 | { | ||
211 | m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); | ||
212 | } | ||
213 | else if (m_Fields[name].FieldType == typeof(int)) | ||
214 | { | ||
215 | int v = Convert.ToInt32(reader[name]); | ||
216 | m_Fields[name].SetValue(row, v); | ||
217 | } | ||
218 | else if (m_Fields[name].FieldType == typeof(uint)) | ||
219 | { | ||
220 | uint v = Convert.ToUInt32(reader[name]); | ||
221 | m_Fields[name].SetValue(row, v); | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | m_Fields[name].SetValue(row, reader[name]); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | if (m_DataField != null) | ||
230 | { | ||
231 | Dictionary<string, string> data = | ||
232 | new Dictionary<string, string>(); | ||
233 | |||
234 | foreach (string col in m_ColumnNames) | ||
235 | { | ||
236 | data[col] = reader[col].ToString(); | ||
237 | if (data[col] == null) | ||
238 | data[col] = String.Empty; | ||
239 | } | ||
240 | |||
241 | m_DataField.SetValue(row, data); | ||
242 | } | ||
243 | |||
244 | result.Add(row); | ||
245 | } | ||
246 | } | ||
247 | cmd.Connection = null; | ||
248 | return result.ToArray(); | ||
249 | } | ||
250 | |||
251 | public virtual T[] Get(string where) | ||
252 | { | ||
253 | using (MySqlCommand cmd = new MySqlCommand()) | ||
254 | { | ||
255 | string query = String.Format("select * from {0} where {1}", | ||
256 | m_Realm, where); | ||
257 | |||
258 | cmd.CommandText = query; | ||
259 | |||
260 | return DoQuery(cmd); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | public virtual bool Store(T row) | ||
265 | { | ||
266 | // m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked"); | ||
267 | |||
268 | using (MySqlCommand cmd = new MySqlCommand()) | ||
269 | { | ||
270 | string query = ""; | ||
271 | List<String> names = new List<String>(); | ||
272 | List<String> values = new List<String>(); | ||
273 | |||
274 | foreach (FieldInfo fi in m_Fields.Values) | ||
275 | { | ||
276 | names.Add(fi.Name); | ||
277 | values.Add("?" + fi.Name); | ||
278 | |||
279 | // Temporarily return more information about what field is unexpectedly null for | ||
280 | // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the | ||
281 | // InventoryTransferModule or we may be required to substitute a DBNull here. | ||
282 | if (fi.GetValue(row) == null) | ||
283 | throw new NullReferenceException( | ||
284 | string.Format( | ||
285 | "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", | ||
286 | fi.Name, row)); | ||
287 | |||
288 | cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); | ||
289 | } | ||
290 | |||
291 | if (m_DataField != null) | ||
292 | { | ||
293 | Dictionary<string, string> data = | ||
294 | (Dictionary<string, string>)m_DataField.GetValue(row); | ||
295 | |||
296 | foreach (KeyValuePair<string, string> kvp in data) | ||
297 | { | ||
298 | names.Add(kvp.Key); | ||
299 | values.Add("?" + kvp.Key); | ||
300 | cmd.Parameters.AddWithValue("?" + kvp.Key, kvp.Value); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; | ||
305 | |||
306 | cmd.CommandText = query; | ||
307 | |||
308 | if (ExecuteNonQuery(cmd) > 0) | ||
309 | return true; | ||
310 | |||
311 | return false; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | public virtual bool Delete(string field, string key) | ||
316 | { | ||
317 | return Delete(new string[] { field }, new string[] { key }); | ||
318 | } | ||
319 | |||
320 | public virtual bool Delete(string[] fields, string[] keys) | ||
321 | { | ||
322 | // m_log.DebugFormat( | ||
323 | // "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}", | ||
324 | // string.Join(",", fields), string.Join(",", keys)); | ||
325 | |||
326 | if (fields.Length != keys.Length) | ||
327 | return false; | ||
328 | |||
329 | List<string> terms = new List<string>(); | ||
330 | |||
331 | using (MySqlCommand cmd = new MySqlCommand()) | ||
332 | { | ||
333 | for (int i = 0 ; i < fields.Length ; i++) | ||
334 | { | ||
335 | cmd.Parameters.AddWithValue(fields[i], keys[i]); | ||
336 | terms.Add("`" + fields[i] + "` = ?" + fields[i]); | ||
337 | } | ||
338 | |||
339 | string where = String.Join(" and ", terms.ToArray()); | ||
340 | |||
341 | string query = String.Format("delete from {0} where {1}", m_Realm, where); | ||
342 | |||
343 | cmd.CommandText = query; | ||
344 | |||
345 | return ExecuteNonQuery(cmd) > 0; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | public long GetCount(string field, string key) | ||
350 | { | ||
351 | return GetCount(new string[] { field }, new string[] { key }); | ||
352 | } | ||
353 | |||
354 | public long GetCount(string[] fields, string[] keys) | ||
355 | { | ||
356 | if (fields.Length != keys.Length) | ||
357 | return 0; | ||
358 | |||
359 | List<string> terms = new List<string>(); | ||
360 | |||
361 | using (MySqlCommand cmd = new MySqlCommand()) | ||
362 | { | ||
363 | for (int i = 0; i < fields.Length; i++) | ||
364 | { | ||
365 | cmd.Parameters.AddWithValue(fields[i], keys[i]); | ||
366 | terms.Add("`" + fields[i] + "` = ?" + fields[i]); | ||
367 | } | ||
368 | |||
369 | string where = String.Join(" and ", terms.ToArray()); | ||
370 | |||
371 | string query = String.Format("select count(*) from {0} where {1}", | ||
372 | m_Realm, where); | ||
373 | |||
374 | cmd.CommandText = query; | ||
375 | |||
376 | Object result = DoQueryScalar(cmd); | ||
377 | |||
378 | return Convert.ToInt64(result); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | public long GetCount(string where) | ||
383 | { | ||
384 | using (MySqlCommand cmd = new MySqlCommand()) | ||
385 | { | ||
386 | string query = String.Format("select count(*) from {0} where {1}", | ||
387 | m_Realm, where); | ||
388 | |||
389 | cmd.CommandText = query; | ||
390 | |||
391 | object result = DoQueryScalar(cmd); | ||
392 | |||
393 | return Convert.ToInt64(result); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | public object DoQueryScalar(MySqlCommand cmd) | ||
398 | { | ||
399 | if (m_trans == null) | ||
400 | { | ||
401 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
402 | { | ||
403 | dbcon.Open(); | ||
404 | cmd.Connection = dbcon; | ||
405 | |||
406 | Object ret = cmd.ExecuteScalar(); | ||
407 | cmd.Connection = null; | ||
408 | dbcon.Close(); | ||
409 | return ret; | ||
410 | } | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | cmd.Connection = m_trans.Connection; | ||
415 | cmd.Transaction = m_trans; | ||
416 | |||
417 | return cmd.ExecuteScalar(); | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLGridUserData.cs b/OpenSim/Data/MySQL/MySQLGridUserData.cs new file mode 100644 index 0000000..00560c1 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLGridUserData.cs | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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..4e73ee7 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLGroupsData.cs | |||
@@ -0,0 +1,483 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 < NOW() - INTERVAL 2 WEEK", m_Realm); | ||
435 | |||
436 | ExecuteNonQuery(cmd); | ||
437 | } | ||
438 | |||
439 | } | ||
440 | } | ||
441 | |||
442 | public class MySqlGroupsNoticesHandler : MySQLGenericTableHandler<NoticeData> | ||
443 | { | ||
444 | protected override Assembly Assembly | ||
445 | { | ||
446 | // WARNING! Moving migrations to this assembly!!! | ||
447 | get { return GetType().Assembly; } | ||
448 | } | ||
449 | |||
450 | public MySqlGroupsNoticesHandler(string connectionString, string realm) | ||
451 | : base(connectionString, realm, string.Empty) | ||
452 | { | ||
453 | } | ||
454 | |||
455 | public void DeleteOld() | ||
456 | { | ||
457 | uint now = (uint)Util.UnixTimeSinceEpoch(); | ||
458 | |||
459 | using (MySqlCommand cmd = new MySqlCommand()) | ||
460 | { | ||
461 | cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm); | ||
462 | cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old | ||
463 | |||
464 | ExecuteNonQuery(cmd); | ||
465 | } | ||
466 | |||
467 | } | ||
468 | } | ||
469 | |||
470 | public class MySqlGroupsPrincipalsHandler : MySQLGenericTableHandler<PrincipalData> | ||
471 | { | ||
472 | protected override Assembly Assembly | ||
473 | { | ||
474 | // WARNING! Moving migrations to this assembly!!! | ||
475 | get { return GetType().Assembly; } | ||
476 | } | ||
477 | |||
478 | public MySqlGroupsPrincipalsHandler(string connectionString, string realm) | ||
479 | : base(connectionString, realm, string.Empty) | ||
480 | { | ||
481 | } | ||
482 | } | ||
483 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLHGTravelData.cs b/OpenSim/Data/MySQL/MySQLHGTravelData.cs new file mode 100644 index 0000000..e81b880 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLHGTravelData.cs | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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..cc787cc --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs | |||
@@ -0,0 +1,916 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /// <summary> | ||
86 | /// The name of this DB provider | ||
87 | /// </summary> | ||
88 | /// <returns>Name of DB provider</returns> | ||
89 | public string Name | ||
90 | { | ||
91 | get { return "MySQL Inventory Data Interface"; } | ||
92 | } | ||
93 | |||
94 | /// <summary> | ||
95 | /// Closes this DB provider | ||
96 | /// </summary> | ||
97 | /// <remarks>do nothing</remarks> | ||
98 | public void Dispose() | ||
99 | { | ||
100 | // Do nothing. | ||
101 | } | ||
102 | |||
103 | /// <summary> | ||
104 | /// Returns a list of items in a specified folder | ||
105 | /// </summary> | ||
106 | /// <param name="folderID">The folder to search</param> | ||
107 | /// <returns>A list containing inventory items</returns> | ||
108 | public List<InventoryItemBase> getInventoryInFolder(UUID folderID) | ||
109 | { | ||
110 | try | ||
111 | { | ||
112 | lock (m_dbLock) | ||
113 | { | ||
114 | List<InventoryItemBase> items = new List<InventoryItemBase>(); | ||
115 | |||
116 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
117 | { | ||
118 | dbcon.Open(); | ||
119 | |||
120 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", dbcon)) | ||
121 | { | ||
122 | result.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
123 | |||
124 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
125 | { | ||
126 | while (reader.Read()) | ||
127 | { | ||
128 | // A null item (because something went wrong) breaks everything in the folder | ||
129 | InventoryItemBase item = readInventoryItem(reader); | ||
130 | if (item != null) | ||
131 | items.Add(item); | ||
132 | } | ||
133 | |||
134 | dbcon.Close(); | ||
135 | return items; | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | catch (Exception e) | ||
142 | { | ||
143 | m_log.Error(e.Message, e); | ||
144 | return null; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /// <summary> | ||
149 | /// Returns a list of the root folders within a users inventory | ||
150 | /// </summary> | ||
151 | /// <param name="user">The user whose inventory is to be searched</param> | ||
152 | /// <returns>A list of folder objects</returns> | ||
153 | public List<InventoryFolderBase> getUserRootFolders(UUID user) | ||
154 | { | ||
155 | try | ||
156 | { | ||
157 | lock (m_dbLock) | ||
158 | { | ||
159 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
160 | { | ||
161 | dbcon.Open(); | ||
162 | |||
163 | using (MySqlCommand result = new MySqlCommand( | ||
164 | "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon)) | ||
165 | { | ||
166 | result.Parameters.AddWithValue("?uuid", user.ToString()); | ||
167 | result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); | ||
168 | |||
169 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
170 | { | ||
171 | List<InventoryFolderBase> items = new List<InventoryFolderBase>(); | ||
172 | while (reader.Read()) | ||
173 | items.Add(readInventoryFolder(reader)); | ||
174 | |||
175 | dbcon.Close(); | ||
176 | return items; | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | catch (Exception e) | ||
183 | { | ||
184 | m_log.Error(e.Message, e); | ||
185 | return null; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | |||
190 | /// <summary> | ||
191 | /// see <see cref="InventoryItemBase.getUserRootFolder"/> | ||
192 | /// </summary> | ||
193 | /// <param name="user">The user UUID</param> | ||
194 | /// <returns></returns> | ||
195 | public InventoryFolderBase getUserRootFolder(UUID user) | ||
196 | { | ||
197 | try | ||
198 | { | ||
199 | lock (m_dbLock) | ||
200 | { | ||
201 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
202 | { | ||
203 | dbcon.Open(); | ||
204 | |||
205 | using (MySqlCommand result = new MySqlCommand( | ||
206 | "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon)) | ||
207 | { | ||
208 | result.Parameters.AddWithValue("?uuid", user.ToString()); | ||
209 | result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); | ||
210 | |||
211 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
212 | { | ||
213 | List<InventoryFolderBase> items = new List<InventoryFolderBase>(); | ||
214 | while (reader.Read()) | ||
215 | items.Add(readInventoryFolder(reader)); | ||
216 | |||
217 | InventoryFolderBase rootFolder = null; | ||
218 | |||
219 | // There should only ever be one root folder for a user. However, if there's more | ||
220 | // than one we'll simply use the first one rather than failing. It would be even | ||
221 | // nicer to print some message to this effect, but this feels like it's too low a | ||
222 | // to put such a message out, and it's too minor right now to spare the time to | ||
223 | // suitably refactor. | ||
224 | if (items.Count > 0) | ||
225 | rootFolder = items[0]; | ||
226 | |||
227 | dbcon.Close(); | ||
228 | return rootFolder; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | catch (Exception e) | ||
235 | { | ||
236 | m_log.Error(e.Message, e); | ||
237 | return null; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /// <summary> | ||
242 | /// Return a list of folders in a users inventory contained within the specified folder. | ||
243 | /// This method is only used in tests - in normal operation the user always have one, | ||
244 | /// and only one, root folder. | ||
245 | /// </summary> | ||
246 | /// <param name="parentID">The folder to search</param> | ||
247 | /// <returns>A list of inventory folders</returns> | ||
248 | public List<InventoryFolderBase> getInventoryFolders(UUID parentID) | ||
249 | { | ||
250 | try | ||
251 | { | ||
252 | lock (m_dbLock) | ||
253 | { | ||
254 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
255 | { | ||
256 | dbcon.Open(); | ||
257 | |||
258 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", dbcon)) | ||
259 | { | ||
260 | result.Parameters.AddWithValue("?uuid", parentID.ToString()); | ||
261 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
262 | { | ||
263 | List<InventoryFolderBase> items = new List<InventoryFolderBase>(); | ||
264 | |||
265 | while (reader.Read()) | ||
266 | items.Add(readInventoryFolder(reader)); | ||
267 | |||
268 | dbcon.Close(); | ||
269 | return items; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | catch (Exception e) | ||
276 | { | ||
277 | m_log.Error(e.Message, e); | ||
278 | return null; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | /// <summary> | ||
283 | /// Reads a one item from an SQL result | ||
284 | /// </summary> | ||
285 | /// <param name="reader">The SQL Result</param> | ||
286 | /// <returns>the item read</returns> | ||
287 | private static InventoryItemBase readInventoryItem(MySqlDataReader reader) | ||
288 | { | ||
289 | try | ||
290 | { | ||
291 | InventoryItemBase item = new InventoryItemBase(); | ||
292 | |||
293 | // TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these. | ||
294 | // (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero) | ||
295 | item.CreatorId = reader["creatorID"].ToString(); | ||
296 | |||
297 | // Be a bit safer in parsing these because the | ||
298 | // database doesn't enforce them to be not null, and | ||
299 | // the inventory still works if these are weird in the | ||
300 | // db | ||
301 | |||
302 | // (Empty is Ok, but "weird" will throw!) | ||
303 | item.Owner = DBGuid.FromDB(reader["avatarID"]); | ||
304 | item.GroupID = DBGuid.FromDB(reader["groupID"]); | ||
305 | |||
306 | // Rest of the parsing. If these UUID's fail, we're dead anyway | ||
307 | item.ID = DBGuid.FromDB(reader["inventoryID"]); | ||
308 | item.AssetID = DBGuid.FromDB(reader["assetID"]); | ||
309 | item.AssetType = (int) reader["assetType"]; | ||
310 | item.Folder = DBGuid.FromDB(reader["parentFolderID"]); | ||
311 | item.Name = (string)(reader["inventoryName"] ?? String.Empty); | ||
312 | item.Description = (string)(reader["inventoryDescription"] ?? String.Empty); | ||
313 | item.NextPermissions = (uint) reader["inventoryNextPermissions"]; | ||
314 | item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"]; | ||
315 | item.InvType = (int) reader["invType"]; | ||
316 | item.BasePermissions = (uint) reader["inventoryBasePermissions"]; | ||
317 | item.EveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"]; | ||
318 | item.GroupPermissions = (uint) reader["inventoryGroupPermissions"]; | ||
319 | item.SalePrice = (int) reader["salePrice"]; | ||
320 | item.SaleType = unchecked((byte)(Convert.ToSByte(reader["saleType"]))); | ||
321 | item.CreationDate = (int) reader["creationDate"]; | ||
322 | item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]); | ||
323 | item.Flags = (uint) reader["flags"]; | ||
324 | |||
325 | return item; | ||
326 | } | ||
327 | catch (MySqlException e) | ||
328 | { | ||
329 | m_log.Error(e.ToString()); | ||
330 | } | ||
331 | |||
332 | return null; | ||
333 | } | ||
334 | |||
335 | /// <summary> | ||
336 | /// Returns a specified inventory item | ||
337 | /// </summary> | ||
338 | /// <param name="item">The item to return</param> | ||
339 | /// <returns>An inventory item</returns> | ||
340 | public InventoryItemBase getInventoryItem(UUID itemID) | ||
341 | { | ||
342 | try | ||
343 | { | ||
344 | lock (m_dbLock) | ||
345 | { | ||
346 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
347 | { | ||
348 | dbcon.Open(); | ||
349 | |||
350 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", dbcon)) | ||
351 | { | ||
352 | result.Parameters.AddWithValue("?uuid", itemID.ToString()); | ||
353 | |||
354 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
355 | { | ||
356 | InventoryItemBase item = null; | ||
357 | if (reader.Read()) | ||
358 | item = readInventoryItem(reader); | ||
359 | |||
360 | dbcon.Close(); | ||
361 | return item; | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | catch (Exception e) | ||
368 | { | ||
369 | m_log.Error(e.Message, e); | ||
370 | } | ||
371 | return null; | ||
372 | } | ||
373 | |||
374 | /// <summary> | ||
375 | /// Reads a list of inventory folders returned by a query. | ||
376 | /// </summary> | ||
377 | /// <param name="reader">A MySQL Data Reader</param> | ||
378 | /// <returns>A List containing inventory folders</returns> | ||
379 | protected static InventoryFolderBase readInventoryFolder(MySqlDataReader reader) | ||
380 | { | ||
381 | try | ||
382 | { | ||
383 | InventoryFolderBase folder = new InventoryFolderBase(); | ||
384 | folder.Owner = DBGuid.FromDB(reader["agentID"]); | ||
385 | folder.ParentID = DBGuid.FromDB(reader["parentFolderID"]); | ||
386 | folder.ID = DBGuid.FromDB(reader["folderID"]); | ||
387 | folder.Name = (string) reader["folderName"]; | ||
388 | folder.Type = (short) reader["type"]; | ||
389 | folder.Version = (ushort) ((int) reader["version"]); | ||
390 | return folder; | ||
391 | } | ||
392 | catch (Exception e) | ||
393 | { | ||
394 | m_log.Error(e.Message, e); | ||
395 | } | ||
396 | |||
397 | return null; | ||
398 | } | ||
399 | |||
400 | |||
401 | /// <summary> | ||
402 | /// Returns a specified inventory folder | ||
403 | /// </summary> | ||
404 | /// <param name="folderID">The folder to return</param> | ||
405 | /// <returns>A folder class</returns> | ||
406 | public InventoryFolderBase getInventoryFolder(UUID folderID) | ||
407 | { | ||
408 | try | ||
409 | { | ||
410 | lock (m_dbLock) | ||
411 | { | ||
412 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
413 | { | ||
414 | dbcon.Open(); | ||
415 | |||
416 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon)) | ||
417 | { | ||
418 | result.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
419 | |||
420 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
421 | { | ||
422 | InventoryFolderBase folder = null; | ||
423 | if (reader.Read()) | ||
424 | folder = readInventoryFolder(reader); | ||
425 | |||
426 | dbcon.Close(); | ||
427 | return folder; | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | catch (Exception e) | ||
434 | { | ||
435 | m_log.Error(e.Message, e); | ||
436 | return null; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | /// <summary> | ||
441 | /// Adds a specified item to the database | ||
442 | /// </summary> | ||
443 | /// <param name="item">The inventory item</param> | ||
444 | public void addInventoryItem(InventoryItemBase item) | ||
445 | { | ||
446 | string sql = | ||
447 | "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName" | ||
448 | + ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType" | ||
449 | + ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, inventoryGroupPermissions, salePrice, saleType" | ||
450 | + ", creationDate, groupID, groupOwned, flags) VALUES "; | ||
451 | sql += | ||
452 | "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription" | ||
453 | + ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID" | ||
454 | + ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?inventoryGroupPermissions, ?salePrice, ?saleType, ?creationDate" | ||
455 | + ", ?groupID, ?groupOwned, ?flags)"; | ||
456 | |||
457 | string itemName = item.Name; | ||
458 | if (item.Name.Length > 64) | ||
459 | { | ||
460 | itemName = item.Name.Substring(0, 64); | ||
461 | m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item"); | ||
462 | } | ||
463 | |||
464 | string itemDesc = item.Description; | ||
465 | if (item.Description.Length > 128) | ||
466 | { | ||
467 | itemDesc = item.Description.Substring(0, 128); | ||
468 | m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length + " to " + itemDesc.Length + " characters on add item"); | ||
469 | } | ||
470 | |||
471 | try | ||
472 | { | ||
473 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
474 | { | ||
475 | dbcon.Open(); | ||
476 | |||
477 | using (MySqlCommand result = new MySqlCommand(sql, dbcon)) | ||
478 | { | ||
479 | result.Parameters.AddWithValue("?inventoryID", item.ID.ToString()); | ||
480 | result.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); | ||
481 | result.Parameters.AddWithValue("?assetType", item.AssetType.ToString()); | ||
482 | result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString()); | ||
483 | result.Parameters.AddWithValue("?avatarID", item.Owner.ToString()); | ||
484 | result.Parameters.AddWithValue("?inventoryName", itemName); | ||
485 | result.Parameters.AddWithValue("?inventoryDescription", itemDesc); | ||
486 | result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString()); | ||
487 | result.Parameters.AddWithValue("?inventoryCurrentPermissions", | ||
488 | item.CurrentPermissions.ToString()); | ||
489 | result.Parameters.AddWithValue("?invType", item.InvType); | ||
490 | result.Parameters.AddWithValue("?creatorID", item.CreatorId); | ||
491 | result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); | ||
492 | result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); | ||
493 | result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); | ||
494 | result.Parameters.AddWithValue("?salePrice", item.SalePrice); | ||
495 | result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType)); | ||
496 | result.Parameters.AddWithValue("?creationDate", item.CreationDate); | ||
497 | result.Parameters.AddWithValue("?groupID", item.GroupID); | ||
498 | result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); | ||
499 | result.Parameters.AddWithValue("?flags", item.Flags); | ||
500 | |||
501 | lock (m_dbLock) | ||
502 | result.ExecuteNonQuery(); | ||
503 | |||
504 | result.Dispose(); | ||
505 | } | ||
506 | |||
507 | using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon)) | ||
508 | { | ||
509 | result.Parameters.AddWithValue("?folderID", item.Folder.ToString()); | ||
510 | |||
511 | lock (m_dbLock) | ||
512 | result.ExecuteNonQuery(); | ||
513 | } | ||
514 | dbcon.Close(); | ||
515 | } | ||
516 | } | ||
517 | catch (MySqlException e) | ||
518 | { | ||
519 | m_log.Error(e.ToString()); | ||
520 | } | ||
521 | } | ||
522 | |||
523 | /// <summary> | ||
524 | /// Updates the specified inventory item | ||
525 | /// </summary> | ||
526 | /// <param name="item">Inventory item to update</param> | ||
527 | public void updateInventoryItem(InventoryItemBase item) | ||
528 | { | ||
529 | addInventoryItem(item); | ||
530 | } | ||
531 | |||
532 | /// <summary> | ||
533 | /// Detele the specified inventory item | ||
534 | /// </summary> | ||
535 | /// <param name="item">The inventory item UUID to delete</param> | ||
536 | public void deleteInventoryItem(UUID itemID) | ||
537 | { | ||
538 | try | ||
539 | { | ||
540 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
541 | { | ||
542 | dbcon.Open(); | ||
543 | |||
544 | using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon)) | ||
545 | { | ||
546 | cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); | ||
547 | |||
548 | lock (m_dbLock) | ||
549 | cmd.ExecuteNonQuery(); | ||
550 | } | ||
551 | dbcon.Close(); | ||
552 | } | ||
553 | } | ||
554 | catch (MySqlException e) | ||
555 | { | ||
556 | m_log.Error(e.Message, e); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | public InventoryItemBase queryInventoryItem(UUID itemID) | ||
561 | { | ||
562 | return getInventoryItem(itemID); | ||
563 | } | ||
564 | |||
565 | public InventoryFolderBase queryInventoryFolder(UUID folderID) | ||
566 | { | ||
567 | return getInventoryFolder(folderID); | ||
568 | } | ||
569 | |||
570 | /// <summary> | ||
571 | /// Creates a new inventory folder | ||
572 | /// </summary> | ||
573 | /// <param name="folder">Folder to create</param> | ||
574 | public void addInventoryFolder(InventoryFolderBase folder) | ||
575 | { | ||
576 | string sql = | ||
577 | "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES "; | ||
578 | sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)"; | ||
579 | |||
580 | string folderName = folder.Name; | ||
581 | if (folderName.Length > 64) | ||
582 | { | ||
583 | folderName = folderName.Substring(0, 64); | ||
584 | m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length + " to " + folderName.Length + " characters on add folder"); | ||
585 | } | ||
586 | |||
587 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
588 | { | ||
589 | dbcon.Open(); | ||
590 | |||
591 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
592 | { | ||
593 | cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); | ||
594 | cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString()); | ||
595 | cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); | ||
596 | cmd.Parameters.AddWithValue("?folderName", folderName); | ||
597 | cmd.Parameters.AddWithValue("?type", folder.Type); | ||
598 | cmd.Parameters.AddWithValue("?version", folder.Version); | ||
599 | |||
600 | try | ||
601 | { | ||
602 | lock (m_dbLock) | ||
603 | { | ||
604 | cmd.ExecuteNonQuery(); | ||
605 | } | ||
606 | } | ||
607 | catch (Exception e) | ||
608 | { | ||
609 | m_log.Error(e.ToString()); | ||
610 | } | ||
611 | } | ||
612 | dbcon.Close(); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | /// <summary> | ||
617 | /// Updates an inventory folder | ||
618 | /// </summary> | ||
619 | /// <param name="folder">Folder to update</param> | ||
620 | public void updateInventoryFolder(InventoryFolderBase folder) | ||
621 | { | ||
622 | addInventoryFolder(folder); | ||
623 | } | ||
624 | |||
625 | /// <summary> | ||
626 | /// Move an inventory folder | ||
627 | /// </summary> | ||
628 | /// <param name="folder">Folder to move</param> | ||
629 | /// <remarks>UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID</remarks> | ||
630 | public void moveInventoryFolder(InventoryFolderBase folder) | ||
631 | { | ||
632 | string sql = | ||
633 | "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID"; | ||
634 | |||
635 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
636 | { | ||
637 | dbcon.Open(); | ||
638 | |||
639 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
640 | { | ||
641 | cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); | ||
642 | cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); | ||
643 | |||
644 | try | ||
645 | { | ||
646 | lock (m_dbLock) | ||
647 | { | ||
648 | cmd.ExecuteNonQuery(); | ||
649 | } | ||
650 | } | ||
651 | catch (Exception e) | ||
652 | { | ||
653 | m_log.Error(e.ToString()); | ||
654 | } | ||
655 | } | ||
656 | dbcon.Close(); | ||
657 | } | ||
658 | } | ||
659 | |||
660 | /// <summary> | ||
661 | /// Append a list of all the child folders of a parent folder | ||
662 | /// </summary> | ||
663 | /// <param name="folders">list where folders will be appended</param> | ||
664 | /// <param name="parentID">ID of parent</param> | ||
665 | protected void getInventoryFolders(ref List<InventoryFolderBase> folders, UUID parentID) | ||
666 | { | ||
667 | List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID); | ||
668 | |||
669 | foreach (InventoryFolderBase f in subfolderList) | ||
670 | folders.Add(f); | ||
671 | } | ||
672 | |||
673 | |||
674 | /// <summary> | ||
675 | /// See IInventoryDataPlugin | ||
676 | /// </summary> | ||
677 | /// <param name="parentID"></param> | ||
678 | /// <returns></returns> | ||
679 | public List<InventoryFolderBase> getFolderHierarchy(UUID parentID) | ||
680 | { | ||
681 | /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one | ||
682 | * - We will only need to hit the database twice instead of n times. | ||
683 | * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned | ||
684 | * by the same person, each user only has 1 inventory heirarchy | ||
685 | * - The returned list is not ordered, instead of breadth-first ordered | ||
686 | There are basically 2 usage cases for getFolderHeirarchy: | ||
687 | 1) Getting the user's entire inventory heirarchy when they log in | ||
688 | 2) Finding a subfolder heirarchy to delete when emptying the trash. | ||
689 | This implementation will pull all inventory folders from the database, and then prune away any folder that | ||
690 | is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the | ||
691 | database than to make n requests. This pays off only if requested heirarchy is large. | ||
692 | By making this choice, we are making the worst case better at the cost of making the best case worse. | ||
693 | This way is generally better because we don't have to rebuild the connection/sql query per subfolder, | ||
694 | even if we end up getting more data from the SQL server than we need. | ||
695 | - Francis | ||
696 | */ | ||
697 | try | ||
698 | { | ||
699 | List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); | ||
700 | Dictionary<UUID, List<InventoryFolderBase>> hashtable = new Dictionary<UUID, List<InventoryFolderBase>>(); ; | ||
701 | List<InventoryFolderBase> parentFolder = new List<InventoryFolderBase>(); | ||
702 | bool buildResultsFromHashTable = false; | ||
703 | |||
704 | lock (m_dbLock) | ||
705 | { | ||
706 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
707 | { | ||
708 | dbcon.Open(); | ||
709 | |||
710 | /* Fetch the parent folder from the database to determine the agent ID, and if | ||
711 | * we're querying the root of the inventory folder tree */ | ||
712 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon)) | ||
713 | { | ||
714 | result.Parameters.AddWithValue("?uuid", parentID.ToString()); | ||
715 | |||
716 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
717 | { | ||
718 | // Should be at most 1 result | ||
719 | while (reader.Read()) | ||
720 | parentFolder.Add(readInventoryFolder(reader)); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | if (parentFolder.Count >= 1) // No result means parent folder does not exist | ||
725 | { | ||
726 | if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder | ||
727 | { | ||
728 | /* Get all of the agent's folders from the database, put them in a list and return it */ | ||
729 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon)) | ||
730 | { | ||
731 | result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); | ||
732 | |||
733 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
734 | { | ||
735 | while (reader.Read()) | ||
736 | { | ||
737 | InventoryFolderBase curFolder = readInventoryFolder(reader); | ||
738 | if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list | ||
739 | folders.Add(curFolder); | ||
740 | } | ||
741 | } | ||
742 | } | ||
743 | } // if we are querying the root folder | ||
744 | else // else we are querying a subtree of the inventory folder tree | ||
745 | { | ||
746 | /* Get all of the agent's folders from the database, put them all in a hash table | ||
747 | * indexed by their parent ID */ | ||
748 | using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon)) | ||
749 | { | ||
750 | result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); | ||
751 | |||
752 | using (MySqlDataReader reader = result.ExecuteReader()) | ||
753 | { | ||
754 | while (reader.Read()) | ||
755 | { | ||
756 | InventoryFolderBase curFolder = readInventoryFolder(reader); | ||
757 | if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling | ||
758 | hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list | ||
759 | else // else current folder has no known (yet) siblings | ||
760 | { | ||
761 | List<InventoryFolderBase> siblingList = new List<InventoryFolderBase>(); | ||
762 | siblingList.Add(curFolder); | ||
763 | // Current folder has no known (yet) siblings | ||
764 | hashtable.Add(curFolder.ParentID, siblingList); | ||
765 | } | ||
766 | } // while more items to read from the database | ||
767 | } | ||
768 | } | ||
769 | |||
770 | // Set flag so we know we need to build the results from the hash table after | ||
771 | // we unlock the database | ||
772 | buildResultsFromHashTable = true; | ||
773 | |||
774 | } // else we are querying a subtree of the inventory folder tree | ||
775 | } // if folder parentID exists | ||
776 | |||
777 | if (buildResultsFromHashTable) | ||
778 | { | ||
779 | /* We have all of the user's folders stored in a hash table indexed by their parent ID | ||
780 | * and we need to return the requested subtree. We will build the requested subtree | ||
781 | * by performing a breadth-first-search on the hash table */ | ||
782 | if (hashtable.ContainsKey(parentID)) | ||
783 | folders.AddRange(hashtable[parentID]); | ||
784 | for (int i = 0; i < folders.Count; i++) // **Note: folders.Count is *not* static | ||
785 | if (hashtable.ContainsKey(folders[i].ID)) | ||
786 | folders.AddRange(hashtable[folders[i].ID]); | ||
787 | } | ||
788 | } | ||
789 | } // lock (database) | ||
790 | |||
791 | return folders; | ||
792 | } | ||
793 | catch (Exception e) | ||
794 | { | ||
795 | m_log.Error(e.Message, e); | ||
796 | return null; | ||
797 | } | ||
798 | } | ||
799 | |||
800 | /// <summary> | ||
801 | /// Delete a folder from database | ||
802 | /// </summary> | ||
803 | /// <param name="folderID">the folder UUID</param> | ||
804 | protected void deleteOneFolder(UUID folderID) | ||
805 | { | ||
806 | try | ||
807 | { | ||
808 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
809 | { | ||
810 | dbcon.Open(); | ||
811 | |||
812 | // System folders can never be deleted. Period. | ||
813 | using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid and type=-1", dbcon)) | ||
814 | { | ||
815 | cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
816 | |||
817 | lock (m_dbLock) | ||
818 | cmd.ExecuteNonQuery(); | ||
819 | } | ||
820 | dbcon.Close(); | ||
821 | } | ||
822 | } | ||
823 | catch (MySqlException e) | ||
824 | { | ||
825 | m_log.Error(e.Message, e); | ||
826 | } | ||
827 | } | ||
828 | |||
829 | /// <summary> | ||
830 | /// Delete all item in a folder | ||
831 | /// </summary> | ||
832 | /// <param name="folderID">the folder UUID</param> | ||
833 | protected void deleteItemsInFolder(UUID folderID) | ||
834 | { | ||
835 | try | ||
836 | { | ||
837 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
838 | { | ||
839 | dbcon.Open(); | ||
840 | |||
841 | using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", dbcon)) | ||
842 | { | ||
843 | cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); | ||
844 | |||
845 | lock (m_dbLock) | ||
846 | cmd.ExecuteNonQuery(); | ||
847 | } | ||
848 | dbcon.Close(); | ||
849 | } | ||
850 | } | ||
851 | catch (MySqlException e) | ||
852 | { | ||
853 | m_log.Error(e.ToString()); | ||
854 | } | ||
855 | } | ||
856 | |||
857 | /// <summary> | ||
858 | /// Deletes an inventory folder | ||
859 | /// </summary> | ||
860 | /// <param name="folderId">Id of folder to delete</param> | ||
861 | public void deleteInventoryFolder(UUID folderID) | ||
862 | { | ||
863 | List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID); | ||
864 | |||
865 | //Delete all sub-folders | ||
866 | foreach (InventoryFolderBase f in subFolders) | ||
867 | { | ||
868 | deleteOneFolder(f.ID); | ||
869 | deleteItemsInFolder(f.ID); | ||
870 | } | ||
871 | |||
872 | //Delete the actual row | ||
873 | deleteOneFolder(folderID); | ||
874 | deleteItemsInFolder(folderID); | ||
875 | } | ||
876 | |||
877 | public List<InventoryItemBase> fetchActiveGestures(UUID avatarID) | ||
878 | { | ||
879 | lock (m_dbLock) | ||
880 | { | ||
881 | try | ||
882 | { | ||
883 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
884 | { | ||
885 | dbcon.Open(); | ||
886 | |||
887 | using (MySqlCommand sqlCmd = new MySqlCommand( | ||
888 | "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags & 1", dbcon)) | ||
889 | { | ||
890 | sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString()); | ||
891 | sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); | ||
892 | |||
893 | using (MySqlDataReader result = sqlCmd.ExecuteReader()) | ||
894 | { | ||
895 | List<InventoryItemBase> list = new List<InventoryItemBase>(); | ||
896 | while (result.Read()) | ||
897 | { | ||
898 | InventoryItemBase item = readInventoryItem(result); | ||
899 | if (item != null) | ||
900 | list.Add(item); | ||
901 | } | ||
902 | dbcon.Close(); | ||
903 | return list; | ||
904 | } | ||
905 | } | ||
906 | } | ||
907 | } | ||
908 | catch (Exception e) | ||
909 | { | ||
910 | m_log.Error(e.Message, e); | ||
911 | return null; | ||
912 | } | ||
913 | } | ||
914 | } | ||
915 | } | ||
916 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLMigrations.cs b/OpenSim/Data/MySQL/MySQLMigrations.cs new file mode 100644 index 0000000..2043dae --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLMigrations.cs | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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/MySQLMuteListData.cs b/OpenSim/Data/MySQL/MySQLMuteListData.cs new file mode 100644 index 0000000..a5935a3 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLMuteListData.cs | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 MySqlMuteListData : MySQLGenericTableHandler<MuteData>, IMuteListData | ||
39 | { | ||
40 | public MySqlMuteListData(string connectionString) | ||
41 | : base(connectionString, "MuteList", "MuteListStore") | ||
42 | { | ||
43 | } | ||
44 | |||
45 | public MuteData[] Get(UUID agentID) | ||
46 | { | ||
47 | MuteData[] data = base.Get("AgentID", agentID.ToString()); | ||
48 | return data; | ||
49 | } | ||
50 | |||
51 | public bool Delete(UUID agentID, UUID muteID, string muteName) | ||
52 | { | ||
53 | string cmnd ="delete from MuteList where AgentID = ?AgentID and MuteID = ?MuteID and MuteName = ?MuteName"; | ||
54 | |||
55 | using (MySqlCommand cmd = new MySqlCommand(cmnd)) | ||
56 | { | ||
57 | cmd.Parameters.AddWithValue("?AgentID", agentID.ToString()); | ||
58 | cmd.Parameters.AddWithValue("?MuteID", muteID.ToString()); | ||
59 | cmd.Parameters.AddWithValue("?MuteName", muteName); | ||
60 | |||
61 | if (ExecuteNonQuery(cmd) > 0) | ||
62 | return true; | ||
63 | return false; | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLOfflineIMData.cs b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs new file mode 100644 index 0000000..7608858 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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..b9114eb --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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", sessionID.ToString()); | ||
56 | |||
57 | if (ret.Length == 0) | ||
58 | return null; | ||
59 | |||
60 | return ret[0]; | ||
61 | } | ||
62 | |||
63 | public PresenceData GetByUser(UUID userID) | ||
64 | { | ||
65 | PresenceData[] ret = Get("UserID", userID.ToString()); | ||
66 | |||
67 | if (ret.Length == 0) | ||
68 | return null; | ||
69 | |||
70 | return ret[0]; | ||
71 | } | ||
72 | |||
73 | public void LogoutRegionAgents(UUID regionID) | ||
74 | { | ||
75 | using (MySqlCommand cmd = new MySqlCommand()) | ||
76 | { | ||
77 | cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm); | ||
78 | |||
79 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
80 | |||
81 | ExecuteNonQuery(cmd); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | public bool ReportAgent(UUID sessionID, UUID regionID) | ||
86 | { | ||
87 | PresenceData[] pd = Get("SessionID", sessionID.ToString()); | ||
88 | if (pd.Length == 0) | ||
89 | return false; | ||
90 | |||
91 | if (regionID == UUID.Zero) | ||
92 | return false; | ||
93 | |||
94 | using (MySqlCommand cmd = new MySqlCommand()) | ||
95 | { | ||
96 | cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm); | ||
97 | |||
98 | cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); | ||
99 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
100 | |||
101 | if (ExecuteNonQuery(cmd) == 0) | ||
102 | return false; | ||
103 | } | ||
104 | |||
105 | return true; | ||
106 | } | ||
107 | |||
108 | public bool VerifyAgent(UUID agentId, UUID secureSessionID) | ||
109 | { | ||
110 | PresenceData[] ret = Get("SecureSessionID", | ||
111 | secureSessionID.ToString()); | ||
112 | |||
113 | if (ret.Length == 0) | ||
114 | return false; | ||
115 | |||
116 | if(ret[0].UserID != agentId.ToString()) | ||
117 | return false; | ||
118 | |||
119 | return true; | ||
120 | } | ||
121 | } | ||
122 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLRaw.cs b/OpenSim/Data/MySQL/MySQLRaw.cs new file mode 100644 index 0000000..bb8c96c --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLRaw.cs | |||
@@ -0,0 +1,197 @@ | |||
1 | // https://dev.mysql.com/doc/connector-net/en/ | ||
2 | |||
3 | |||
4 | using System; | ||
5 | using System.Collections; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Data; | ||
8 | using System.Reflection; | ||
9 | using System.Text; | ||
10 | using log4net; | ||
11 | using MySql.Data.MySqlClient; | ||
12 | |||
13 | namespace OpenSim.Data.MySQL | ||
14 | { | ||
15 | public class MySQLRaw | ||
16 | { | ||
17 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
18 | private string m_connectString; | ||
19 | |||
20 | public MySQLRaw(string connect) | ||
21 | { | ||
22 | m_connectString = connect; | ||
23 | } | ||
24 | |||
25 | public int Count(string table) | ||
26 | { | ||
27 | return Count(table, ""); | ||
28 | } | ||
29 | public int Count(string table, string wher) | ||
30 | { | ||
31 | string query = "SELECT Count(*) FROM " + table; | ||
32 | if ("" != wher) | ||
33 | query = query + " WHERE " + wher; | ||
34 | int result = -1; | ||
35 | |||
36 | object r = doScalarQuery(query); | ||
37 | if (r != null) | ||
38 | result = Convert.ToInt32(r); | ||
39 | |||
40 | return result; | ||
41 | } | ||
42 | |||
43 | public List< Hashtable > Join(string table, string select, string join, string wher, string order) | ||
44 | { | ||
45 | if ("" == select) | ||
46 | select = "*"; | ||
47 | string query = "SELECT " + select + " FROM " + table; | ||
48 | if ("" != join) | ||
49 | query = query + " " + join; | ||
50 | if ("" != wher) | ||
51 | query = query + " WHERE " + wher; | ||
52 | if ("" != order) | ||
53 | query = query + " ORDER BY " + order; | ||
54 | |||
55 | using (MySqlConnection dbcon = new MySqlConnection(m_connectString)) | ||
56 | { | ||
57 | dbcon.Open(); | ||
58 | MySqlCommand cmd = new MySqlCommand(query, dbcon); | ||
59 | MySqlDataReader rdr = cmd.ExecuteReader(); | ||
60 | List<string> names = new List<string>(); | ||
61 | DataTable schema = rdr.GetSchemaTable(); | ||
62 | List< Hashtable > list = new List< Hashtable >(); | ||
63 | |||
64 | foreach (DataRow row in schema.Rows) | ||
65 | { | ||
66 | string tbl = ""; | ||
67 | string nm = ""; | ||
68 | string tp = ""; | ||
69 | foreach (DataColumn col in schema.Columns) | ||
70 | { | ||
71 | if ("BaseTableName" == col.ColumnName) tbl = row[col].ToString(); | ||
72 | if ("ColumnName" == col.ColumnName) nm = row[col].ToString(); | ||
73 | if ("DataType" == col.ColumnName) tp = row[col].ToString(); | ||
74 | } | ||
75 | names.Add(nm); | ||
76 | } | ||
77 | |||
78 | while (rdr.Read()) | ||
79 | { | ||
80 | Hashtable r = new Hashtable(); | ||
81 | foreach (string name in names) | ||
82 | { | ||
83 | r[name] = rdr[name]; | ||
84 | } | ||
85 | list.Add(r); | ||
86 | } | ||
87 | |||
88 | rdr.Close(); | ||
89 | dbcon.Close(); | ||
90 | return list; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | public List< Hashtable > Select(string table, string select, string wher, string order) | ||
95 | { | ||
96 | if ("" == select) | ||
97 | select = "*"; | ||
98 | string query = "SELECT " + select + " FROM " + table; | ||
99 | if ("" != wher) | ||
100 | query = query + " WHERE " + wher; | ||
101 | if ("" != order) | ||
102 | query = query + " ORDER BY " + order; | ||
103 | |||
104 | using (MySqlConnection dbcon = new MySqlConnection(m_connectString)) | ||
105 | { | ||
106 | dbcon.Open(); | ||
107 | MySqlCommand cmd = new MySqlCommand(query, dbcon); | ||
108 | MySqlDataReader rdr = cmd.ExecuteReader(); | ||
109 | List<string> names = new List<string>(); | ||
110 | DataTable schema = rdr.GetSchemaTable(); | ||
111 | List< Hashtable > list = new List< Hashtable >(); | ||
112 | |||
113 | foreach (DataRow row in schema.Rows) | ||
114 | { | ||
115 | string tbl = ""; | ||
116 | string nm = ""; | ||
117 | string tp = ""; | ||
118 | foreach (DataColumn col in schema.Columns) | ||
119 | { | ||
120 | if ("BaseTableName" == col.ColumnName) tbl = row[col].ToString(); | ||
121 | if ("ColumnName" == col.ColumnName) nm = row[col].ToString(); | ||
122 | if ("DataType" == col.ColumnName) tp = row[col].ToString(); | ||
123 | } | ||
124 | names.Add(nm); | ||
125 | } | ||
126 | |||
127 | while (rdr.Read()) | ||
128 | { | ||
129 | Hashtable r = new Hashtable(); | ||
130 | foreach (string name in names) | ||
131 | { | ||
132 | r[name] = rdr[name]; | ||
133 | } | ||
134 | list.Add(r); | ||
135 | } | ||
136 | |||
137 | rdr.Close(); | ||
138 | dbcon.Close(); | ||
139 | return list; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | private object doScalarQuery(string query) | ||
144 | { | ||
145 | try | ||
146 | { | ||
147 | using (MySqlConnection dbcon = new MySqlConnection(m_connectString)) | ||
148 | { | ||
149 | dbcon.Open(); | ||
150 | MySqlCommand cmd = new MySqlCommand(query, dbcon); | ||
151 | Object ret = cmd.ExecuteScalar(); | ||
152 | dbcon.Close(); | ||
153 | return ret; | ||
154 | } | ||
155 | } | ||
156 | catch (MySqlException e) | ||
157 | { | ||
158 | m_log.ErrorFormat("[MYSQL RAW]: Problem connecting to the database {0}", e.Message); | ||
159 | return null; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | private void doNonQuery(string query) | ||
164 | { | ||
165 | using (MySqlConnection dbcon = new MySqlConnection(m_connectString)) | ||
166 | { | ||
167 | dbcon.Open(); | ||
168 | MySqlCommand cmd = new MySqlCommand(query, dbcon); | ||
169 | cmd.ExecuteNonQuery(); | ||
170 | dbcon.Close(); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | public void Insert(string table) | ||
175 | { | ||
176 | string query = "INSERT INTO " + table + " (name, age) VALUES('John Smith', '33')"; | ||
177 | doNonQuery(query); | ||
178 | } | ||
179 | |||
180 | public void Update(string table, string wher) | ||
181 | { | ||
182 | string query = "UPDATE " + table + " SET name='Joe', age='22'"; | ||
183 | if ("" != wher) | ||
184 | query = query + " WHERE " + wher; | ||
185 | doNonQuery(query); | ||
186 | } | ||
187 | |||
188 | public void Delete(string table, string wher) | ||
189 | { | ||
190 | string query = "DELETE FROM " + table; | ||
191 | if ("" != wher) | ||
192 | query = query + " WHERE " + wher; | ||
193 | doNonQuery(query); | ||
194 | } | ||
195 | |||
196 | } | ||
197 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs new file mode 100644 index 0000000..46df421 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | public List<RegionData> Get(string regionName, UUID scopeID) | ||
68 | { | ||
69 | string command = "select * from `"+m_Realm+"` where regionName like ?regionName"; | ||
70 | if (scopeID != UUID.Zero) | ||
71 | command += " and ScopeID = ?scopeID"; | ||
72 | |||
73 | command += " order by regionName"; | ||
74 | |||
75 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
76 | { | ||
77 | cmd.Parameters.AddWithValue("?regionName", regionName); | ||
78 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
79 | |||
80 | return RunCommand(cmd); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | public RegionData Get(int posX, int posY, UUID scopeID) | ||
85 | { | ||
86 | /* fixed size regions | ||
87 | string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY"; | ||
88 | if (scopeID != UUID.Zero) | ||
89 | command += " and ScopeID = ?scopeID"; | ||
90 | |||
91 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
92 | { | ||
93 | cmd.Parameters.AddWithValue("?posX", posX.ToString()); | ||
94 | cmd.Parameters.AddWithValue("?posY", posY.ToString()); | ||
95 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
96 | |||
97 | List<RegionData> ret = RunCommand(cmd); | ||
98 | if (ret.Count == 0) | ||
99 | return null; | ||
100 | |||
101 | return ret[0]; | ||
102 | } | ||
103 | */ | ||
104 | // extend database search for maximum region size area | ||
105 | string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY"; | ||
106 | if (scopeID != UUID.Zero) | ||
107 | command += " and ScopeID = ?scopeID"; | ||
108 | |||
109 | int startX = posX - (int)Constants.MaximumRegionSize; | ||
110 | int startY = posY - (int)Constants.MaximumRegionSize; | ||
111 | int endX = posX; | ||
112 | int endY = posY; | ||
113 | |||
114 | List<RegionData> ret; | ||
115 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
116 | { | ||
117 | cmd.Parameters.AddWithValue("?startX", startX.ToString()); | ||
118 | cmd.Parameters.AddWithValue("?startY", startY.ToString()); | ||
119 | cmd.Parameters.AddWithValue("?endX", endX.ToString()); | ||
120 | cmd.Parameters.AddWithValue("?endY", endY.ToString()); | ||
121 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
122 | |||
123 | ret = RunCommand(cmd); | ||
124 | } | ||
125 | |||
126 | if (ret.Count == 0) | ||
127 | return null; | ||
128 | |||
129 | // find the first that contains pos | ||
130 | RegionData rg = null; | ||
131 | foreach (RegionData r in ret) | ||
132 | { | ||
133 | if (posX >= r.posX && posX < r.posX + r.sizeX | ||
134 | && posY >= r.posY && posY < r.posY + r.sizeY) | ||
135 | { | ||
136 | rg = r; | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | return rg; | ||
142 | } | ||
143 | |||
144 | public RegionData Get(UUID regionID, UUID scopeID) | ||
145 | { | ||
146 | string command = "select * from `"+m_Realm+"` where uuid = ?regionID"; | ||
147 | if (scopeID != UUID.Zero) | ||
148 | command += " and ScopeID = ?scopeID"; | ||
149 | |||
150 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
151 | { | ||
152 | cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); | ||
153 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
154 | |||
155 | List<RegionData> ret = RunCommand(cmd); | ||
156 | if (ret.Count == 0) | ||
157 | return null; | ||
158 | |||
159 | return ret[0]; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID) | ||
164 | { | ||
165 | /* fix size regions | ||
166 | string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY"; | ||
167 | if (scopeID != UUID.Zero) | ||
168 | command += " and ScopeID = ?scopeID"; | ||
169 | |||
170 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
171 | { | ||
172 | cmd.Parameters.AddWithValue("?startX", startX.ToString()); | ||
173 | cmd.Parameters.AddWithValue("?startY", startY.ToString()); | ||
174 | cmd.Parameters.AddWithValue("?endX", endX.ToString()); | ||
175 | cmd.Parameters.AddWithValue("?endY", endY.ToString()); | ||
176 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
177 | |||
178 | return RunCommand(cmd); | ||
179 | } | ||
180 | */ | ||
181 | string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY"; | ||
182 | if (scopeID != UUID.Zero) | ||
183 | command += " and ScopeID = ?scopeID"; | ||
184 | |||
185 | int qstartX = startX - (int)Constants.MaximumRegionSize; | ||
186 | int qstartY = startY - (int)Constants.MaximumRegionSize; | ||
187 | |||
188 | List<RegionData> dbret; | ||
189 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
190 | { | ||
191 | cmd.Parameters.AddWithValue("?startX", qstartX.ToString()); | ||
192 | cmd.Parameters.AddWithValue("?startY", qstartY.ToString()); | ||
193 | cmd.Parameters.AddWithValue("?endX", endX.ToString()); | ||
194 | cmd.Parameters.AddWithValue("?endY", endY.ToString()); | ||
195 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
196 | |||
197 | dbret = RunCommand(cmd); | ||
198 | } | ||
199 | |||
200 | List<RegionData> ret = new List<RegionData>(); | ||
201 | |||
202 | if (dbret.Count == 0) | ||
203 | return ret; | ||
204 | |||
205 | foreach (RegionData r in dbret) | ||
206 | { | ||
207 | if (r.posX + r.sizeX > startX && r.posX <= endX | ||
208 | && r.posY + r.sizeY > startY && r.posY <= endY) | ||
209 | ret.Add(r); | ||
210 | } | ||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | public List<RegionData> RunCommand(MySqlCommand cmd) | ||
215 | { | ||
216 | List<RegionData> retList = new List<RegionData>(); | ||
217 | |||
218 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
219 | { | ||
220 | dbcon.Open(); | ||
221 | cmd.Connection = dbcon; | ||
222 | |||
223 | using (IDataReader result = cmd.ExecuteReader()) | ||
224 | { | ||
225 | while (result.Read()) | ||
226 | { | ||
227 | RegionData ret = new RegionData(); | ||
228 | ret.Data = new Dictionary<string, object>(); | ||
229 | |||
230 | ret.RegionID = DBGuid.FromDB(result["uuid"]); | ||
231 | ret.ScopeID = DBGuid.FromDB(result["ScopeID"]); | ||
232 | |||
233 | ret.RegionName = result["regionName"].ToString(); | ||
234 | ret.posX = Convert.ToInt32(result["locX"]); | ||
235 | ret.posY = Convert.ToInt32(result["locY"]); | ||
236 | ret.sizeX = Convert.ToInt32(result["sizeX"]); | ||
237 | ret.sizeY = Convert.ToInt32(result["sizeY"]); | ||
238 | |||
239 | CheckColumnNames(result); | ||
240 | |||
241 | foreach (string s in m_ColumnNames) | ||
242 | { | ||
243 | if (s == "uuid") | ||
244 | continue; | ||
245 | if (s == "ScopeID") | ||
246 | continue; | ||
247 | if (s == "regionName") | ||
248 | continue; | ||
249 | if (s == "locX") | ||
250 | continue; | ||
251 | if (s == "locY") | ||
252 | continue; | ||
253 | |||
254 | object value = result[s]; | ||
255 | if (value is DBNull) | ||
256 | ret.Data[s] = null; | ||
257 | else | ||
258 | ret.Data[s] = result[s].ToString(); | ||
259 | } | ||
260 | |||
261 | retList.Add(ret); | ||
262 | } | ||
263 | } | ||
264 | cmd.Connection = null; | ||
265 | dbcon.Close(); | ||
266 | } | ||
267 | |||
268 | return retList; | ||
269 | } | ||
270 | |||
271 | private void CheckColumnNames(IDataReader result) | ||
272 | { | ||
273 | if (m_ColumnNames != null) | ||
274 | return; | ||
275 | |||
276 | List<string> columnNames = new List<string>(); | ||
277 | |||
278 | DataTable schemaTable = result.GetSchemaTable(); | ||
279 | foreach (DataRow row in schemaTable.Rows) | ||
280 | { | ||
281 | if (row["ColumnName"] != null) | ||
282 | columnNames.Add(row["ColumnName"].ToString()); | ||
283 | } | ||
284 | |||
285 | m_ColumnNames = columnNames; | ||
286 | } | ||
287 | |||
288 | public bool Store(RegionData data) | ||
289 | { | ||
290 | if (data.Data.ContainsKey("uuid")) | ||
291 | data.Data.Remove("uuid"); | ||
292 | if (data.Data.ContainsKey("ScopeID")) | ||
293 | data.Data.Remove("ScopeID"); | ||
294 | if (data.Data.ContainsKey("regionName")) | ||
295 | data.Data.Remove("regionName"); | ||
296 | if (data.Data.ContainsKey("posX")) | ||
297 | data.Data.Remove("posX"); | ||
298 | if (data.Data.ContainsKey("posY")) | ||
299 | data.Data.Remove("posY"); | ||
300 | if (data.Data.ContainsKey("sizeX")) | ||
301 | data.Data.Remove("sizeX"); | ||
302 | if (data.Data.ContainsKey("sizeY")) | ||
303 | data.Data.Remove("sizeY"); | ||
304 | if (data.Data.ContainsKey("locX")) | ||
305 | data.Data.Remove("locX"); | ||
306 | if (data.Data.ContainsKey("locY")) | ||
307 | data.Data.Remove("locY"); | ||
308 | |||
309 | if (data.RegionName.Length > 128) | ||
310 | data.RegionName = data.RegionName.Substring(0, 128); | ||
311 | |||
312 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
313 | |||
314 | using (MySqlCommand cmd = new MySqlCommand()) | ||
315 | { | ||
316 | string update = "update `" + m_Realm + "` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY"; | ||
317 | foreach (string field in fields) | ||
318 | { | ||
319 | update += ", "; | ||
320 | update += "`" + field + "` = ?" + field; | ||
321 | |||
322 | cmd.Parameters.AddWithValue("?" + field, data.Data[field]); | ||
323 | } | ||
324 | |||
325 | update += " where uuid = ?regionID"; | ||
326 | |||
327 | if (data.ScopeID != UUID.Zero) | ||
328 | update += " and ScopeID = ?scopeID"; | ||
329 | |||
330 | cmd.CommandText = update; | ||
331 | cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); | ||
332 | cmd.Parameters.AddWithValue("?regionName", data.RegionName); | ||
333 | cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); | ||
334 | cmd.Parameters.AddWithValue("?posX", data.posX.ToString()); | ||
335 | cmd.Parameters.AddWithValue("?posY", data.posY.ToString()); | ||
336 | cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString()); | ||
337 | cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString()); | ||
338 | |||
339 | if (ExecuteNonQuery(cmd) < 1) | ||
340 | { | ||
341 | string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" + | ||
342 | String.Join("`, `", fields) + | ||
343 | "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")"; | ||
344 | |||
345 | cmd.CommandText = insert; | ||
346 | |||
347 | if (ExecuteNonQuery(cmd) < 1) | ||
348 | { | ||
349 | return false; | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | return true; | ||
355 | } | ||
356 | |||
357 | public bool SetDataItem(UUID regionID, string item, string value) | ||
358 | { | ||
359 | using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where uuid = ?UUID")) | ||
360 | { | ||
361 | cmd.Parameters.AddWithValue("?" + item, value); | ||
362 | cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); | ||
363 | |||
364 | if (ExecuteNonQuery(cmd) > 0) | ||
365 | return true; | ||
366 | } | ||
367 | |||
368 | return false; | ||
369 | } | ||
370 | |||
371 | public bool Delete(UUID regionID) | ||
372 | { | ||
373 | using (MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + "` where uuid = ?UUID")) | ||
374 | { | ||
375 | cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); | ||
376 | |||
377 | if (ExecuteNonQuery(cmd) > 0) | ||
378 | return true; | ||
379 | } | ||
380 | |||
381 | return false; | ||
382 | } | ||
383 | |||
384 | public List<RegionData> GetDefaultRegions(UUID scopeID) | ||
385 | { | ||
386 | return Get((int)RegionFlags.DefaultRegion, scopeID); | ||
387 | } | ||
388 | |||
389 | public List<RegionData> GetDefaultHypergridRegions(UUID scopeID) | ||
390 | { | ||
391 | return Get((int)RegionFlags.DefaultHGRegion, scopeID); | ||
392 | } | ||
393 | |||
394 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) | ||
395 | { | ||
396 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); | ||
397 | RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y); | ||
398 | regions.Sort(distanceComparer); | ||
399 | return regions; | ||
400 | } | ||
401 | |||
402 | public List<RegionData> GetHyperlinks(UUID scopeID) | ||
403 | { | ||
404 | return Get((int)RegionFlags.Hyperlink, scopeID); | ||
405 | } | ||
406 | |||
407 | private List<RegionData> Get(int regionFlags, UUID scopeID) | ||
408 | { | ||
409 | string command = "select * from `" + m_Realm + "` where (flags & " + regionFlags.ToString() + ") <> 0"; | ||
410 | if (scopeID != UUID.Zero) | ||
411 | command += " and ScopeID = ?scopeID"; | ||
412 | |||
413 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
414 | { | ||
415 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
416 | |||
417 | return RunCommand(cmd); | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs new file mode 100644 index 0000000..e754522 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs | |||
@@ -0,0 +1,2337 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 virtual void Initialise(string connectionString) | ||
80 | { | ||
81 | m_connectionString = connectionString; | ||
82 | |||
83 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
84 | { | ||
85 | dbcon.Open(); | ||
86 | |||
87 | // Apply new Migrations | ||
88 | // | ||
89 | Migration m = new Migration(dbcon, Assembly, "RegionStore"); | ||
90 | m.Update(); | ||
91 | dbcon.Close(); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | private IDataReader ExecuteReader(MySqlCommand c) | ||
96 | { | ||
97 | IDataReader r = null; | ||
98 | |||
99 | try | ||
100 | { | ||
101 | r = c.ExecuteReader(); | ||
102 | } | ||
103 | catch (Exception e) | ||
104 | { | ||
105 | m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e); | ||
106 | throw; | ||
107 | } | ||
108 | |||
109 | return r; | ||
110 | } | ||
111 | |||
112 | private void ExecuteNonQuery(MySqlCommand c) | ||
113 | { | ||
114 | try | ||
115 | { | ||
116 | c.ExecuteNonQuery(); | ||
117 | } | ||
118 | catch (Exception e) | ||
119 | { | ||
120 | m_log.Error("[REGION DB]: MySQL error in ExecuteNonQuery: " + e.Message); | ||
121 | throw; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | public void Dispose() {} | ||
126 | |||
127 | public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID) | ||
128 | { | ||
129 | uint flags = obj.RootPart.GetEffectiveObjectFlags(); | ||
130 | |||
131 | // Eligibility check | ||
132 | // | ||
133 | // PrimFlags.Temporary is not used in OpenSim code and cannot | ||
134 | // be guaranteed to always be clear. Don't check it. | ||
135 | // if ((flags & (uint)PrimFlags.Temporary) != 0) | ||
136 | // return; | ||
137 | if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) | ||
138 | return; | ||
139 | |||
140 | lock (m_dbLock) | ||
141 | { | ||
142 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
143 | { | ||
144 | dbcon.Open(); | ||
145 | |||
146 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
147 | { | ||
148 | foreach (SceneObjectPart prim in obj.Parts) | ||
149 | { | ||
150 | cmd.Parameters.Clear(); | ||
151 | |||
152 | cmd.CommandText = "replace into prims (" + | ||
153 | "UUID, CreationDate, " + | ||
154 | "Name, Text, Description, " + | ||
155 | "SitName, TouchName, ObjectFlags, " + | ||
156 | "OwnerMask, NextOwnerMask, GroupMask, " + | ||
157 | "EveryoneMask, BaseMask, PositionX, " + | ||
158 | "PositionY, PositionZ, GroupPositionX, " + | ||
159 | "GroupPositionY, GroupPositionZ, VelocityX, " + | ||
160 | "VelocityY, VelocityZ, AngularVelocityX, " + | ||
161 | "AngularVelocityY, AngularVelocityZ, " + | ||
162 | "AccelerationX, AccelerationY, " + | ||
163 | "AccelerationZ, RotationX, " + | ||
164 | "RotationY, RotationZ, " + | ||
165 | "RotationW, SitTargetOffsetX, " + | ||
166 | "SitTargetOffsetY, SitTargetOffsetZ, " + | ||
167 | "SitTargetOrientW, SitTargetOrientX, " + | ||
168 | "SitTargetOrientY, SitTargetOrientZ, " + | ||
169 | "RegionUUID, CreatorID, " + | ||
170 | "OwnerID, GroupID, " + | ||
171 | "LastOwnerID, RezzerID, SceneGroupID, " + | ||
172 | "PayPrice, PayButton1, " + | ||
173 | "PayButton2, PayButton3, " + | ||
174 | "PayButton4, LoopedSound, " + | ||
175 | "LoopedSoundGain, TextureAnimation, " + | ||
176 | "OmegaX, OmegaY, OmegaZ, " + | ||
177 | "CameraEyeOffsetX, CameraEyeOffsetY, " + | ||
178 | "CameraEyeOffsetZ, CameraAtOffsetX, " + | ||
179 | "CameraAtOffsetY, CameraAtOffsetZ, " + | ||
180 | "ForceMouselook, ScriptAccessPin, " + | ||
181 | "AllowedDrop, DieAtEdge, " + | ||
182 | "SalePrice, SaleType, " + | ||
183 | "ColorR, ColorG, ColorB, ColorA, " + | ||
184 | "ParticleSystem, ClickAction, Material, " + | ||
185 | "CollisionSound, CollisionSoundVolume, " + | ||
186 | "PassTouches, " + | ||
187 | "PassCollisions, " + | ||
188 | "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " + | ||
189 | "AttachedPosY, AttachedPosZ, " + | ||
190 | "PhysicsShapeType, Density, GravityModifier, " + | ||
191 | "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " + | ||
192 | "RotationAxisLocks" + | ||
193 | ") values (" + "?UUID, " + | ||
194 | "?CreationDate, ?Name, ?Text, " + | ||
195 | "?Description, ?SitName, ?TouchName, " + | ||
196 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + | ||
197 | "?GroupMask, ?EveryoneMask, ?BaseMask, " + | ||
198 | "?PositionX, ?PositionY, ?PositionZ, " + | ||
199 | "?GroupPositionX, ?GroupPositionY, " + | ||
200 | "?GroupPositionZ, ?VelocityX, " + | ||
201 | "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + | ||
202 | "?AngularVelocityY, ?AngularVelocityZ, " + | ||
203 | "?AccelerationX, ?AccelerationY, " + | ||
204 | "?AccelerationZ, ?RotationX, " + | ||
205 | "?RotationY, ?RotationZ, " + | ||
206 | "?RotationW, ?SitTargetOffsetX, " + | ||
207 | "?SitTargetOffsetY, ?SitTargetOffsetZ, " + | ||
208 | "?SitTargetOrientW, ?SitTargetOrientX, " + | ||
209 | "?SitTargetOrientY, ?SitTargetOrientZ, " + | ||
210 | "?RegionUUID, ?CreatorID, ?OwnerID, " + | ||
211 | "?GroupID, ?LastOwnerID, ?RezzerID, ?SceneGroupID, " + | ||
212 | "?PayPrice, ?PayButton1, ?PayButton2, " + | ||
213 | "?PayButton3, ?PayButton4, ?LoopedSound, " + | ||
214 | "?LoopedSoundGain, ?TextureAnimation, " + | ||
215 | "?OmegaX, ?OmegaY, ?OmegaZ, " + | ||
216 | "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + | ||
217 | "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + | ||
218 | "?CameraAtOffsetY, ?CameraAtOffsetZ, " + | ||
219 | "?ForceMouselook, ?ScriptAccessPin, " + | ||
220 | "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + | ||
221 | "?SaleType, ?ColorR, ?ColorG, " + | ||
222 | "?ColorB, ?ColorA, ?ParticleSystem, " + | ||
223 | "?ClickAction, ?Material, ?CollisionSound, " + | ||
224 | "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " + | ||
225 | "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " + | ||
226 | "?AttachedPosY, ?AttachedPosZ, " + | ||
227 | "?PhysicsShapeType, ?Density, ?GravityModifier, " + | ||
228 | "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," + | ||
229 | "?RotationAxisLocks)"; | ||
230 | |||
231 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); | ||
232 | |||
233 | ExecuteNonQuery(cmd); | ||
234 | |||
235 | cmd.Parameters.Clear(); | ||
236 | |||
237 | cmd.CommandText = "replace into primshapes (" + | ||
238 | "UUID, Shape, ScaleX, ScaleY, " + | ||
239 | "ScaleZ, PCode, PathBegin, PathEnd, " + | ||
240 | "PathScaleX, PathScaleY, PathShearX, " + | ||
241 | "PathShearY, PathSkew, PathCurve, " + | ||
242 | "PathRadiusOffset, PathRevolutions, " + | ||
243 | "PathTaperX, PathTaperY, PathTwist, " + | ||
244 | "PathTwistBegin, ProfileBegin, ProfileEnd, " + | ||
245 | "ProfileCurve, ProfileHollow, Texture, " + | ||
246 | "ExtraParams, State, LastAttachPoint, Media) " + | ||
247 | "values (?UUID, " + | ||
248 | "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + | ||
249 | "?PCode, ?PathBegin, ?PathEnd, " + | ||
250 | "?PathScaleX, ?PathScaleY, " + | ||
251 | "?PathShearX, ?PathShearY, " + | ||
252 | "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + | ||
253 | "?PathRevolutions, ?PathTaperX, " + | ||
254 | "?PathTaperY, ?PathTwist, " + | ||
255 | "?PathTwistBegin, ?ProfileBegin, " + | ||
256 | "?ProfileEnd, ?ProfileCurve, " + | ||
257 | "?ProfileHollow, ?Texture, ?ExtraParams, " + | ||
258 | "?State, ?LastAttachPoint, ?Media)"; | ||
259 | |||
260 | FillShapeCommand(cmd, prim); | ||
261 | |||
262 | ExecuteNonQuery(cmd); | ||
263 | } | ||
264 | } | ||
265 | dbcon.Close(); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | |||
270 | public virtual void RemoveObject(UUID obj, UUID regionUUID) | ||
271 | { | ||
272 | // m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID); | ||
273 | |||
274 | List<UUID> uuids = new List<UUID>(); | ||
275 | |||
276 | // Formerly, this used to check the region UUID. | ||
277 | // That makes no sense, as we remove the contents of a prim | ||
278 | // unconditionally, but the prim dependent on the region ID. | ||
279 | // So, we would destroy an object and cause hard to detect | ||
280 | // issues if we delete the contents only. Deleting it all may | ||
281 | // cause the loss of a prim, but is cleaner. | ||
282 | // It's also faster because it uses the primary key. | ||
283 | // | ||
284 | lock (m_dbLock) | ||
285 | { | ||
286 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
287 | { | ||
288 | dbcon.Open(); | ||
289 | |||
290 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
291 | { | ||
292 | cmd.CommandText = "select UUID from prims where SceneGroupID= ?UUID"; | ||
293 | cmd.Parameters.AddWithValue("UUID", obj.ToString()); | ||
294 | |||
295 | using (IDataReader reader = ExecuteReader(cmd)) | ||
296 | { | ||
297 | while (reader.Read()) | ||
298 | uuids.Add(DBGuid.FromDB(reader["UUID"].ToString())); | ||
299 | } | ||
300 | |||
301 | // delete the main prims | ||
302 | cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; | ||
303 | ExecuteNonQuery(cmd); | ||
304 | } | ||
305 | dbcon.Close(); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | // there is no way this should be < 1 unless there is | ||
310 | // a very corrupt database, but in that case be extra | ||
311 | // safe anyway. | ||
312 | if (uuids.Count > 0) | ||
313 | { | ||
314 | RemoveShapes(uuids); | ||
315 | RemoveItems(uuids); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /// <summary> | ||
320 | /// Remove all persisted items of the given prim. | ||
321 | /// The caller must acquire the necessrary synchronization locks | ||
322 | /// </summary> | ||
323 | /// <param name="uuid">the Item UUID</param> | ||
324 | private void RemoveItems(UUID uuid) | ||
325 | { | ||
326 | // locked by caller | ||
327 | // lock (m_dbLock) | ||
328 | { | ||
329 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
330 | { | ||
331 | dbcon.Open(); | ||
332 | |||
333 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
334 | { | ||
335 | cmd.CommandText = "delete from primitems where PrimID = ?PrimID"; | ||
336 | cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); | ||
337 | |||
338 | ExecuteNonQuery(cmd); | ||
339 | } | ||
340 | dbcon.Close(); | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /// <summary> | ||
346 | /// Remove all persisted shapes for a list of prims | ||
347 | /// The caller must acquire the necessrary synchronization locks | ||
348 | /// </summary> | ||
349 | /// <param name="uuids">the list of UUIDs</param> | ||
350 | private void RemoveShapes(List<UUID> uuids) | ||
351 | { | ||
352 | lock (m_dbLock) | ||
353 | { | ||
354 | string sql = "delete from primshapes where "; | ||
355 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
356 | { | ||
357 | dbcon.Open(); | ||
358 | |||
359 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
360 | { | ||
361 | for (int i = 0; i < uuids.Count; i++) | ||
362 | { | ||
363 | if ((i + 1) == uuids.Count) | ||
364 | {// end of the list | ||
365 | sql += "(UUID = ?UUID" + i + ")"; | ||
366 | } | ||
367 | else | ||
368 | { | ||
369 | sql += "(UUID = ?UUID" + i + ") or "; | ||
370 | } | ||
371 | } | ||
372 | cmd.CommandText = sql; | ||
373 | |||
374 | for (int i = 0; i < uuids.Count; i++) | ||
375 | cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); | ||
376 | |||
377 | ExecuteNonQuery(cmd); | ||
378 | } | ||
379 | dbcon.Close(); | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /// <summary> | ||
385 | /// Remove all persisted items for a list of prims | ||
386 | /// The caller must acquire the necessrary synchronization locks | ||
387 | /// </summary> | ||
388 | /// <param name="uuids">the list of UUIDs</param> | ||
389 | private void RemoveItems(List<UUID> uuids) | ||
390 | { | ||
391 | lock (m_dbLock) | ||
392 | { | ||
393 | string sql = "delete from primitems where "; | ||
394 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
395 | { | ||
396 | dbcon.Open(); | ||
397 | |||
398 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
399 | { | ||
400 | for (int i = 0; i < uuids.Count; i++) | ||
401 | { | ||
402 | if ((i + 1) == uuids.Count) | ||
403 | { | ||
404 | // end of the list | ||
405 | sql += "(PrimID = ?PrimID" + i + ")"; | ||
406 | } | ||
407 | else | ||
408 | { | ||
409 | sql += "(PrimID = ?PrimID" + i + ") or "; | ||
410 | } | ||
411 | } | ||
412 | cmd.CommandText = sql; | ||
413 | |||
414 | for (int i = 0; i < uuids.Count; i++) | ||
415 | cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); | ||
416 | |||
417 | ExecuteNonQuery(cmd); | ||
418 | } | ||
419 | dbcon.Close(); | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | |||
424 | public virtual List<SceneObjectGroup> LoadObjects(UUID regionID) | ||
425 | { | ||
426 | const int ROWS_PER_QUERY = 5000; | ||
427 | |||
428 | Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(ROWS_PER_QUERY); | ||
429 | Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>(); | ||
430 | int count = 0; | ||
431 | |||
432 | #region Prim Loading | ||
433 | |||
434 | lock (m_dbLock) | ||
435 | { | ||
436 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
437 | { | ||
438 | dbcon.Open(); | ||
439 | |||
440 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
441 | { | ||
442 | cmd.CommandText = | ||
443 | "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID"; | ||
444 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
445 | cmd.CommandTimeout = 3600; | ||
446 | |||
447 | using (IDataReader reader = ExecuteReader(cmd)) | ||
448 | { | ||
449 | while (reader.Read()) | ||
450 | { | ||
451 | SceneObjectPart prim = BuildPrim(reader); | ||
452 | if (reader["Shape"] is DBNull) | ||
453 | prim.Shape = PrimitiveBaseShape.Default; | ||
454 | else | ||
455 | prim.Shape = BuildShape(reader); | ||
456 | |||
457 | UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString()); | ||
458 | if (parentID != prim.UUID) | ||
459 | prim.ParentUUID = parentID; | ||
460 | |||
461 | prims[prim.UUID] = prim; | ||
462 | |||
463 | ++count; | ||
464 | if (count % ROWS_PER_QUERY == 0) | ||
465 | m_log.Debug("[REGION DB]: Loaded " + count + " prims..."); | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | dbcon.Close(); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | #endregion Prim Loading | ||
474 | |||
475 | #region SceneObjectGroup Creation | ||
476 | |||
477 | // Create all of the SOGs from the root prims first | ||
478 | foreach (SceneObjectPart prim in prims.Values) | ||
479 | { | ||
480 | if (prim.ParentUUID == UUID.Zero) | ||
481 | { | ||
482 | objects[prim.UUID] = new SceneObjectGroup(prim); | ||
483 | } | ||
484 | } | ||
485 | |||
486 | // Add all of the children objects to the SOGs | ||
487 | foreach (SceneObjectPart prim in prims.Values) | ||
488 | { | ||
489 | SceneObjectGroup sog; | ||
490 | if (prim.UUID != prim.ParentUUID) | ||
491 | { | ||
492 | if (objects.TryGetValue(prim.ParentUUID, out sog)) | ||
493 | { | ||
494 | int originalLinkNum = prim.LinkNum; | ||
495 | |||
496 | sog.AddPart(prim); | ||
497 | |||
498 | // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. | ||
499 | // We override that here | ||
500 | if (originalLinkNum != 0) | ||
501 | prim.LinkNum = originalLinkNum; | ||
502 | } | ||
503 | else | ||
504 | { | ||
505 | m_log.WarnFormat( | ||
506 | "[REGION DB]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.", | ||
507 | prim.Name, prim.UUID, regionID, prim.ParentUUID); | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | |||
512 | #endregion SceneObjectGroup Creation | ||
513 | |||
514 | m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); | ||
515 | |||
516 | #region Prim Inventory Loading | ||
517 | |||
518 | // Instead of attempting to LoadItems on every prim, | ||
519 | // most of which probably have no items... get a | ||
520 | // list from DB of all prims which have items and | ||
521 | // LoadItems only on those | ||
522 | List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>(); | ||
523 | lock (m_dbLock) | ||
524 | { | ||
525 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
526 | { | ||
527 | dbcon.Open(); | ||
528 | |||
529 | using (MySqlCommand itemCmd = dbcon.CreateCommand()) | ||
530 | { | ||
531 | itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems"; | ||
532 | using (IDataReader itemReader = ExecuteReader(itemCmd)) | ||
533 | { | ||
534 | while (itemReader.Read()) | ||
535 | { | ||
536 | if (!(itemReader["primID"] is DBNull)) | ||
537 | { | ||
538 | UUID primID = DBGuid.FromDB(itemReader["primID"].ToString()); | ||
539 | if (prims.ContainsKey(primID)) | ||
540 | primsWithInventory.Add(prims[primID]); | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | dbcon.Close(); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | foreach (SceneObjectPart prim in primsWithInventory) | ||
550 | { | ||
551 | LoadItems(prim); | ||
552 | } | ||
553 | |||
554 | #endregion Prim Inventory Loading | ||
555 | |||
556 | m_log.DebugFormat("[REGION DB]: Loaded inventory from {0} objects", primsWithInventory.Count); | ||
557 | |||
558 | return new List<SceneObjectGroup>(objects.Values); | ||
559 | } | ||
560 | |||
561 | /// <summary> | ||
562 | /// Load in a prim's persisted inventory. | ||
563 | /// </summary> | ||
564 | /// <param name="prim">The prim</param> | ||
565 | private void LoadItems(SceneObjectPart prim) | ||
566 | { | ||
567 | lock (m_dbLock) | ||
568 | { | ||
569 | List<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); | ||
570 | |||
571 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
572 | { | ||
573 | dbcon.Open(); | ||
574 | |||
575 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
576 | { | ||
577 | cmd.CommandText = "select * from primitems where PrimID = ?PrimID"; | ||
578 | cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); | ||
579 | |||
580 | using (IDataReader reader = ExecuteReader(cmd)) | ||
581 | { | ||
582 | while (reader.Read()) | ||
583 | { | ||
584 | TaskInventoryItem item = BuildItem(reader); | ||
585 | |||
586 | item.ParentID = prim.UUID; // Values in database are often wrong | ||
587 | inventory.Add(item); | ||
588 | } | ||
589 | } | ||
590 | } | ||
591 | dbcon.Close(); | ||
592 | } | ||
593 | |||
594 | prim.Inventory.RestoreInventoryItems(inventory); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | // Legacy entry point for when terrain was always a 256x256 hieghtmap | ||
599 | public void StoreTerrain(double[,] ter, UUID regionID) | ||
600 | { | ||
601 | StoreTerrain(new HeightmapTerrainData(ter), regionID); | ||
602 | } | ||
603 | |||
604 | public void StoreTerrain(TerrainData terrData, UUID regionID) | ||
605 | { | ||
606 | Util.FireAndForget(delegate(object x) | ||
607 | { | ||
608 | m_log.Info("[REGION DB]: Storing terrain"); | ||
609 | |||
610 | int terrainDBRevision; | ||
611 | Array terrainDBblob; | ||
612 | terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); | ||
613 | |||
614 | lock (m_dbLock) | ||
615 | { | ||
616 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
617 | { | ||
618 | dbcon.Open(); | ||
619 | |||
620 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
621 | { | ||
622 | cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; | ||
623 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
624 | |||
625 | using (MySqlCommand cmd2 = dbcon.CreateCommand()) | ||
626 | { | ||
627 | try | ||
628 | { | ||
629 | cmd2.CommandText = "insert into terrain (RegionUUID, " + | ||
630 | "Revision, Heightfield) values (?RegionUUID, " + | ||
631 | "?Revision, ?Heightfield)"; | ||
632 | |||
633 | cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
634 | cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); | ||
635 | cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); | ||
636 | |||
637 | ExecuteNonQuery(cmd); | ||
638 | ExecuteNonQuery(cmd2); | ||
639 | } | ||
640 | catch (Exception e) | ||
641 | { | ||
642 | m_log.ErrorFormat(e.ToString()); | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | dbcon.Close(); | ||
647 | } | ||
648 | } | ||
649 | }); | ||
650 | } | ||
651 | |||
652 | public void StoreBakedTerrain(TerrainData terrData, UUID regionID) | ||
653 | { | ||
654 | Util.FireAndForget(delegate(object x) | ||
655 | { | ||
656 | m_log.Info("[REGION DB]: Storing Baked terrain"); | ||
657 | |||
658 | int terrainDBRevision; | ||
659 | Array terrainDBblob; | ||
660 | terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); | ||
661 | |||
662 | lock (m_dbLock) | ||
663 | { | ||
664 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
665 | { | ||
666 | dbcon.Open(); | ||
667 | |||
668 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
669 | { | ||
670 | cmd.CommandText = "delete from bakedterrain where RegionUUID = ?RegionUUID"; | ||
671 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
672 | |||
673 | using (MySqlCommand cmd2 = dbcon.CreateCommand()) | ||
674 | { | ||
675 | try | ||
676 | { | ||
677 | cmd2.CommandText = "insert into bakedterrain (RegionUUID, " + | ||
678 | "Revision, Heightfield) values (?RegionUUID, " + | ||
679 | "?Revision, ?Heightfield)"; | ||
680 | |||
681 | cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
682 | cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); | ||
683 | cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); | ||
684 | |||
685 | ExecuteNonQuery(cmd); | ||
686 | ExecuteNonQuery(cmd2); | ||
687 | } | ||
688 | catch (Exception e) | ||
689 | { | ||
690 | m_log.ErrorFormat(e.ToString()); | ||
691 | } | ||
692 | } | ||
693 | } | ||
694 | dbcon.Close(); | ||
695 | } | ||
696 | } | ||
697 | }); | ||
698 | } | ||
699 | |||
700 | // Legacy region loading | ||
701 | public virtual double[,] LoadTerrain(UUID regionID) | ||
702 | { | ||
703 | double[,] ret = null; | ||
704 | TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); | ||
705 | if (terrData != null) | ||
706 | ret = terrData.GetDoubles(); | ||
707 | return ret; | ||
708 | } | ||
709 | |||
710 | // Returns 'null' if region not found | ||
711 | public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) | ||
712 | { | ||
713 | TerrainData terrData = null; | ||
714 | byte[] blob = null; | ||
715 | int rev = 0; | ||
716 | |||
717 | lock (m_dbLock) | ||
718 | { | ||
719 | |||
720 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
721 | { | ||
722 | dbcon.Open(); | ||
723 | |||
724 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
725 | { | ||
726 | cmd.CommandText = "select RegionUUID, Revision, Heightfield " + | ||
727 | "from terrain where RegionUUID = ?RegionUUID " + | ||
728 | "order by Revision desc limit 1"; | ||
729 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
730 | |||
731 | using (IDataReader reader = ExecuteReader(cmd)) | ||
732 | { | ||
733 | while (reader.Read()) | ||
734 | { | ||
735 | rev = Convert.ToInt32(reader["Revision"]); | ||
736 | if ((reader["Heightfield"] != DBNull.Value)) | ||
737 | { | ||
738 | blob = (byte[])reader["Heightfield"]; | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | } | ||
743 | dbcon.Close(); | ||
744 | } | ||
745 | } | ||
746 | |||
747 | if(blob != null) | ||
748 | terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); | ||
749 | |||
750 | return terrData; | ||
751 | } | ||
752 | |||
753 | public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) | ||
754 | { | ||
755 | TerrainData terrData = null; | ||
756 | byte[] blob = null; | ||
757 | int rev = 0; | ||
758 | |||
759 | lock (m_dbLock) | ||
760 | { | ||
761 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
762 | { | ||
763 | dbcon.Open(); | ||
764 | |||
765 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
766 | { | ||
767 | cmd.CommandText = "select RegionUUID, Revision, Heightfield " + | ||
768 | "from bakedterrain where RegionUUID = ?RegionUUID "; | ||
769 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
770 | |||
771 | using (IDataReader reader = ExecuteReader(cmd)) | ||
772 | { | ||
773 | while (reader.Read()) | ||
774 | { | ||
775 | rev = Convert.ToInt32(reader["Revision"]); | ||
776 | if ((reader["Heightfield"] != DBNull.Value)) | ||
777 | { | ||
778 | blob = (byte[])reader["Heightfield"]; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | } | ||
783 | dbcon.Close(); | ||
784 | } | ||
785 | } | ||
786 | if(blob != null) | ||
787 | terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); | ||
788 | |||
789 | return terrData; | ||
790 | } | ||
791 | |||
792 | public virtual void RemoveLandObject(UUID globalID) | ||
793 | { | ||
794 | lock (m_dbLock) | ||
795 | { | ||
796 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
797 | { | ||
798 | dbcon.Open(); | ||
799 | |||
800 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
801 | { | ||
802 | cmd.CommandText = "delete from land where UUID = ?UUID"; | ||
803 | cmd.Parameters.AddWithValue("UUID", globalID.ToString()); | ||
804 | |||
805 | ExecuteNonQuery(cmd); | ||
806 | } | ||
807 | dbcon.Close(); | ||
808 | } | ||
809 | } | ||
810 | } | ||
811 | |||
812 | public virtual void StoreLandObject(ILandObject parcel) | ||
813 | { | ||
814 | lock (m_dbLock) | ||
815 | { | ||
816 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
817 | { | ||
818 | dbcon.Open(); | ||
819 | |||
820 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
821 | { | ||
822 | cmd.CommandText = "replace into land (UUID, RegionUUID, " + | ||
823 | "LocalLandID, Bitmap, Name, Description, " + | ||
824 | "OwnerUUID, IsGroupOwned, Area, AuctionID, " + | ||
825 | "Category, ClaimDate, ClaimPrice, GroupUUID, " + | ||
826 | "SalePrice, LandStatus, LandFlags, LandingType, " + | ||
827 | "MediaAutoScale, MediaTextureUUID, MediaURL, " + | ||
828 | "MusicURL, PassHours, PassPrice, SnapshotUUID, " + | ||
829 | "UserLocationX, UserLocationY, UserLocationZ, " + | ||
830 | "UserLookAtX, UserLookAtY, UserLookAtZ, " + | ||
831 | "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " + | ||
832 | "MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " + | ||
833 | "SeeAVs, AnyAVSounds, GroupAVSounds) values (" + | ||
834 | "?UUID, ?RegionUUID, " + | ||
835 | "?LocalLandID, ?Bitmap, ?Name, ?Description, " + | ||
836 | "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + | ||
837 | "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " + | ||
838 | "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " + | ||
839 | "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " + | ||
840 | "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + | ||
841 | "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + | ||
842 | "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + | ||
843 | "?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+ | ||
844 | "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia, " + | ||
845 | "?SeeAVs, ?AnyAVSounds, ?GroupAVSounds)"; | ||
846 | |||
847 | FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); | ||
848 | |||
849 | ExecuteNonQuery(cmd); | ||
850 | |||
851 | cmd.CommandText = "delete from landaccesslist where LandUUID = ?UUID"; | ||
852 | |||
853 | ExecuteNonQuery(cmd); | ||
854 | |||
855 | cmd.Parameters.Clear(); | ||
856 | cmd.CommandText = "insert into landaccesslist (LandUUID, " + | ||
857 | "AccessUUID, Flags, Expires) values (?LandUUID, ?AccessUUID, " + | ||
858 | "?Flags, ?Expires)"; | ||
859 | |||
860 | foreach (LandAccessEntry entry in parcel.LandData.ParcelAccessList) | ||
861 | { | ||
862 | FillLandAccessCommand(cmd, entry, parcel.LandData.GlobalID); | ||
863 | ExecuteNonQuery(cmd); | ||
864 | cmd.Parameters.Clear(); | ||
865 | } | ||
866 | } | ||
867 | dbcon.Close(); | ||
868 | } | ||
869 | } | ||
870 | } | ||
871 | |||
872 | public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) | ||
873 | { | ||
874 | RegionLightShareData nWP = new RegionLightShareData(); | ||
875 | nWP.OnSave += StoreRegionWindlightSettings; | ||
876 | |||
877 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
878 | { | ||
879 | dbcon.Open(); | ||
880 | |||
881 | string command = "select * from `regionwindlight` where region_id = ?regionID"; | ||
882 | |||
883 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
884 | { | ||
885 | cmd.Connection = dbcon; | ||
886 | |||
887 | cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); | ||
888 | |||
889 | using(IDataReader result = ExecuteReader(cmd)) | ||
890 | { | ||
891 | if(!result.Read()) | ||
892 | { | ||
893 | //No result, so store our default windlight profile and return it | ||
894 | nWP.regionID = regionUUID; | ||
895 | // StoreRegionWindlightSettings(nWP); | ||
896 | return nWP; | ||
897 | } | ||
898 | else | ||
899 | { | ||
900 | nWP.regionID = DBGuid.FromDB(result["region_id"]); | ||
901 | nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); | ||
902 | nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); | ||
903 | nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); | ||
904 | nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); | ||
905 | nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); | ||
906 | nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); | ||
907 | nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); | ||
908 | nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); | ||
909 | nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); | ||
910 | nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); | ||
911 | nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); | ||
912 | nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); | ||
913 | nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); | ||
914 | nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); | ||
915 | nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); | ||
916 | nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); | ||
917 | nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); | ||
918 | UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture); | ||
919 | nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); | ||
920 | nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); | ||
921 | nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); | ||
922 | nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); | ||
923 | nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); | ||
924 | nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); | ||
925 | nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); | ||
926 | nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); | ||
927 | nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); | ||
928 | nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); | ||
929 | nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); | ||
930 | nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); | ||
931 | nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); | ||
932 | nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); | ||
933 | nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); | ||
934 | nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); | ||
935 | nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); | ||
936 | nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); | ||
937 | nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); | ||
938 | nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); | ||
939 | nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); | ||
940 | nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); | ||
941 | nWP.eastAngle = Convert.ToSingle(result["east_angle"]); | ||
942 | nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); | ||
943 | nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); | ||
944 | nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); | ||
945 | nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); | ||
946 | nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); | ||
947 | nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); | ||
948 | nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); | ||
949 | nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); | ||
950 | nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); | ||
951 | nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); | ||
952 | nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); | ||
953 | nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); | ||
954 | nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); | ||
955 | nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); | ||
956 | nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); | ||
957 | nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); | ||
958 | nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); | ||
959 | nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); | ||
960 | nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); | ||
961 | nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); | ||
962 | nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); | ||
963 | nWP.valid = true; | ||
964 | } | ||
965 | } | ||
966 | } | ||
967 | dbcon.Close(); | ||
968 | } | ||
969 | |||
970 | return nWP; | ||
971 | } | ||
972 | |||
973 | public virtual RegionSettings LoadRegionSettings(UUID regionUUID) | ||
974 | { | ||
975 | RegionSettings rs = null; | ||
976 | bool needStore = false; | ||
977 | |||
978 | lock (m_dbLock) | ||
979 | { | ||
980 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
981 | { | ||
982 | dbcon.Open(); | ||
983 | |||
984 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
985 | { | ||
986 | cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID"; | ||
987 | cmd.Parameters.AddWithValue("regionUUID", regionUUID); | ||
988 | |||
989 | using (IDataReader reader = ExecuteReader(cmd)) | ||
990 | { | ||
991 | if (reader.Read()) | ||
992 | { | ||
993 | rs = BuildRegionSettings(reader); | ||
994 | rs.OnSave += StoreRegionSettings; | ||
995 | } | ||
996 | else | ||
997 | { | ||
998 | rs = new RegionSettings(); | ||
999 | rs.RegionUUID = regionUUID; | ||
1000 | rs.OnSave += StoreRegionSettings; | ||
1001 | |||
1002 | needStore = true; | ||
1003 | } | ||
1004 | } | ||
1005 | } | ||
1006 | dbcon.Close(); | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | if(needStore) | ||
1011 | StoreRegionSettings(rs); | ||
1012 | |||
1013 | LoadSpawnPoints(rs); | ||
1014 | |||
1015 | return rs; | ||
1016 | } | ||
1017 | |||
1018 | public virtual void StoreRegionWindlightSettings(RegionLightShareData wl) | ||
1019 | { | ||
1020 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1021 | { | ||
1022 | dbcon.Open(); | ||
1023 | |||
1024 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1025 | { | ||
1026 | cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, " | ||
1027 | + "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, " | ||
1028 | + "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, " | ||
1029 | + "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, " | ||
1030 | + "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, " | ||
1031 | + "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, " | ||
1032 | + "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, " | ||
1033 | + "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, " | ||
1034 | + "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, " | ||
1035 | + "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, " | ||
1036 | + "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, " | ||
1037 | + "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, " | ||
1038 | + "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, " | ||
1039 | + "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, " | ||
1040 | + "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, " | ||
1041 | + "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, " | ||
1042 | + "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, " | ||
1043 | + "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, " | ||
1044 | + "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, " | ||
1045 | + "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, " | ||
1046 | + "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, " | ||
1047 | + "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, " | ||
1048 | + "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, " | ||
1049 | + "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, " | ||
1050 | + "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)" | ||
1051 | ; | ||
1052 | |||
1053 | cmd.Parameters.AddWithValue("region_id", wl.regionID); | ||
1054 | cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); | ||
1055 | cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); | ||
1056 | cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); | ||
1057 | cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); | ||
1058 | cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); | ||
1059 | cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); | ||
1060 | cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); | ||
1061 | cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); | ||
1062 | cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); | ||
1063 | cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); | ||
1064 | cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); | ||
1065 | cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); | ||
1066 | cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); | ||
1067 | cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); | ||
1068 | cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); | ||
1069 | cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); | ||
1070 | cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); | ||
1071 | cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); | ||
1072 | cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); | ||
1073 | cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); | ||
1074 | cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); | ||
1075 | cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); | ||
1076 | cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); | ||
1077 | cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); | ||
1078 | cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); | ||
1079 | cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); | ||
1080 | cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); | ||
1081 | cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); | ||
1082 | cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); | ||
1083 | cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); | ||
1084 | cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); | ||
1085 | cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); | ||
1086 | cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); | ||
1087 | cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); | ||
1088 | cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); | ||
1089 | cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); | ||
1090 | cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); | ||
1091 | cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); | ||
1092 | cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); | ||
1093 | cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); | ||
1094 | cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); | ||
1095 | cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); | ||
1096 | cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); | ||
1097 | cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); | ||
1098 | cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); | ||
1099 | cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); | ||
1100 | cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); | ||
1101 | cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); | ||
1102 | cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); | ||
1103 | cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); | ||
1104 | cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); | ||
1105 | cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); | ||
1106 | cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); | ||
1107 | cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); | ||
1108 | cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); | ||
1109 | cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); | ||
1110 | cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); | ||
1111 | cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); | ||
1112 | cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); | ||
1113 | cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); | ||
1114 | cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); | ||
1115 | cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); | ||
1116 | |||
1117 | ExecuteNonQuery(cmd); | ||
1118 | } | ||
1119 | dbcon.Close(); | ||
1120 | } | ||
1121 | } | ||
1122 | |||
1123 | public virtual void RemoveRegionWindlightSettings(UUID regionID) | ||
1124 | { | ||
1125 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1126 | { | ||
1127 | dbcon.Open(); | ||
1128 | |||
1129 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1130 | { | ||
1131 | cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; | ||
1132 | cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); | ||
1133 | ExecuteNonQuery(cmd); | ||
1134 | } | ||
1135 | dbcon.Close(); | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | #region RegionEnvironmentSettings | ||
1140 | public string LoadRegionEnvironmentSettings(UUID regionUUID) | ||
1141 | { | ||
1142 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1143 | { | ||
1144 | dbcon.Open(); | ||
1145 | |||
1146 | string command = "select * from `regionenvironment` where region_id = ?region_id"; | ||
1147 | |||
1148 | using (MySqlCommand cmd = new MySqlCommand(command)) | ||
1149 | { | ||
1150 | cmd.Connection = dbcon; | ||
1151 | |||
1152 | cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); | ||
1153 | |||
1154 | using(IDataReader result = ExecuteReader(cmd)) | ||
1155 | { | ||
1156 | if(!result.Read()) | ||
1157 | { | ||
1158 | dbcon.Close(); | ||
1159 | return String.Empty; | ||
1160 | } | ||
1161 | else | ||
1162 | { | ||
1163 | string ret = Convert.ToString(result["llsd_settings"]); | ||
1164 | dbcon.Close(); | ||
1165 | return ret; | ||
1166 | } | ||
1167 | } | ||
1168 | } | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) | ||
1173 | { | ||
1174 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1175 | { | ||
1176 | dbcon.Open(); | ||
1177 | |||
1178 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1179 | { | ||
1180 | cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; | ||
1181 | |||
1182 | cmd.Parameters.AddWithValue("region_id", regionUUID); | ||
1183 | cmd.Parameters.AddWithValue("llsd_settings", settings); | ||
1184 | |||
1185 | ExecuteNonQuery(cmd); | ||
1186 | } | ||
1187 | dbcon.Close(); | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | public void RemoveRegionEnvironmentSettings(UUID regionUUID) | ||
1192 | { | ||
1193 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1194 | { | ||
1195 | dbcon.Open(); | ||
1196 | |||
1197 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1198 | { | ||
1199 | cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; | ||
1200 | cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); | ||
1201 | ExecuteNonQuery(cmd); | ||
1202 | } | ||
1203 | dbcon.Close(); | ||
1204 | } | ||
1205 | } | ||
1206 | #endregion | ||
1207 | |||
1208 | public virtual void StoreRegionSettings(RegionSettings rs) | ||
1209 | { | ||
1210 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1211 | { | ||
1212 | dbcon.Open(); | ||
1213 | |||
1214 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1215 | { | ||
1216 | cmd.CommandText = "replace into regionsettings (regionUUID, " + | ||
1217 | "block_terraform, block_fly, allow_damage, " + | ||
1218 | "restrict_pushing, allow_land_resell, " + | ||
1219 | "allow_land_join_divide, block_show_in_search, " + | ||
1220 | "agent_limit, object_bonus, maturity, " + | ||
1221 | "disable_scripts, disable_collisions, " + | ||
1222 | "disable_physics, terrain_texture_1, " + | ||
1223 | "terrain_texture_2, terrain_texture_3, " + | ||
1224 | "terrain_texture_4, elevation_1_nw, " + | ||
1225 | "elevation_2_nw, elevation_1_ne, " + | ||
1226 | "elevation_2_ne, elevation_1_se, " + | ||
1227 | "elevation_2_se, elevation_1_sw, " + | ||
1228 | "elevation_2_sw, water_height, " + | ||
1229 | "terrain_raise_limit, terrain_lower_limit, " + | ||
1230 | "use_estate_sun, fixed_sun, sun_position, " + | ||
1231 | "covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " + | ||
1232 | "sunvectorz, loaded_creation_datetime, " + | ||
1233 | "loaded_creation_id, map_tile_ID, block_search, casino, " + | ||
1234 | "TelehubObject, parcel_tile_ID) " + | ||
1235 | "values (?RegionUUID, ?BlockTerraform, " + | ||
1236 | "?BlockFly, ?AllowDamage, ?RestrictPushing, " + | ||
1237 | "?AllowLandResell, ?AllowLandJoinDivide, " + | ||
1238 | "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + | ||
1239 | "?Maturity, ?DisableScripts, ?DisableCollisions, " + | ||
1240 | "?DisablePhysics, ?TerrainTexture1, " + | ||
1241 | "?TerrainTexture2, ?TerrainTexture3, " + | ||
1242 | "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + | ||
1243 | "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + | ||
1244 | "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + | ||
1245 | "?WaterHeight, ?TerrainRaiseLimit, " + | ||
1246 | "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + | ||
1247 | "?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " + | ||
1248 | "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + | ||
1249 | "?LoadedCreationDateTime, ?LoadedCreationID, " + | ||
1250 | "?TerrainImageID, ?block_search, ?casino, " + | ||
1251 | "?TelehubObject, ?ParcelImageID)"; | ||
1252 | |||
1253 | FillRegionSettingsCommand(cmd, rs); | ||
1254 | ExecuteNonQuery(cmd); | ||
1255 | } | ||
1256 | dbcon.Close(); | ||
1257 | SaveSpawnPoints(rs); | ||
1258 | } | ||
1259 | } | ||
1260 | |||
1261 | public virtual List<LandData> LoadLandObjects(UUID regionUUID) | ||
1262 | { | ||
1263 | List<LandData> landData = new List<LandData>(); | ||
1264 | |||
1265 | lock (m_dbLock) | ||
1266 | { | ||
1267 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
1268 | { | ||
1269 | dbcon.Open(); | ||
1270 | |||
1271 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1272 | { | ||
1273 | cmd.CommandText = "select * from land where RegionUUID = ?RegionUUID"; | ||
1274 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1275 | |||
1276 | using (IDataReader reader = ExecuteReader(cmd)) | ||
1277 | { | ||
1278 | while (reader.Read()) | ||
1279 | { | ||
1280 | LandData newLand = BuildLandData(reader); | ||
1281 | landData.Add(newLand); | ||
1282 | } | ||
1283 | } | ||
1284 | } | ||
1285 | |||
1286 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
1287 | { | ||
1288 | foreach (LandData land in landData) | ||
1289 | { | ||
1290 | cmd.Parameters.Clear(); | ||
1291 | cmd.CommandText = "select * from landaccesslist where LandUUID = ?LandUUID"; | ||
1292 | cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); | ||
1293 | |||
1294 | using (IDataReader reader = ExecuteReader(cmd)) | ||
1295 | { | ||
1296 | while (reader.Read()) | ||
1297 | { | ||
1298 | land.ParcelAccessList.Add(BuildLandAccessData(reader)); | ||
1299 | } | ||
1300 | } | ||
1301 | } | ||
1302 | } | ||
1303 | dbcon.Close(); | ||
1304 | } | ||
1305 | } | ||
1306 | |||
1307 | return landData; | ||
1308 | } | ||
1309 | |||
1310 | public void Shutdown() | ||
1311 | { | ||
1312 | } | ||
1313 | |||
1314 | private SceneObjectPart BuildPrim(IDataReader row) | ||
1315 | { | ||
1316 | SceneObjectPart prim = new SceneObjectPart(); | ||
1317 | |||
1318 | // depending on the MySQL connector version, CHAR(36) may be already converted to Guid! | ||
1319 | prim.UUID = DBGuid.FromDB(row["UUID"]); | ||
1320 | prim.CreatorIdentification = (string)row["CreatorID"]; | ||
1321 | prim.OwnerID = DBGuid.FromDB(row["OwnerID"]); | ||
1322 | prim.GroupID = DBGuid.FromDB(row["GroupID"]); | ||
1323 | prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]); | ||
1324 | if (row["RezzerID"] != DBNull.Value) | ||
1325 | prim.RezzerID = DBGuid.FromDB(row["RezzerID"]); | ||
1326 | else | ||
1327 | prim.RezzerID = UUID.Zero; | ||
1328 | |||
1329 | // explicit conversion of integers is required, which sort | ||
1330 | // of sucks. No idea if there is a shortcut here or not. | ||
1331 | prim.CreationDate = (int)row["CreationDate"]; | ||
1332 | if (row["Name"] != DBNull.Value) | ||
1333 | prim.Name = (string)row["Name"]; | ||
1334 | else | ||
1335 | prim.Name = String.Empty; | ||
1336 | // Various text fields | ||
1337 | prim.Text = (string)row["Text"]; | ||
1338 | prim.Color = Color.FromArgb((int)row["ColorA"], | ||
1339 | (int)row["ColorR"], | ||
1340 | (int)row["ColorG"], | ||
1341 | (int)row["ColorB"]); | ||
1342 | prim.Description = (string)row["Description"]; | ||
1343 | prim.SitName = (string)row["SitName"]; | ||
1344 | prim.TouchName = (string)row["TouchName"]; | ||
1345 | // Permissions | ||
1346 | prim.Flags = (PrimFlags)(int)row["ObjectFlags"]; | ||
1347 | prim.OwnerMask = (uint)(int)row["OwnerMask"]; | ||
1348 | prim.NextOwnerMask = (uint)(int)row["NextOwnerMask"]; | ||
1349 | prim.GroupMask = (uint)(int)row["GroupMask"]; | ||
1350 | prim.EveryoneMask = (uint)(int)row["EveryoneMask"]; | ||
1351 | prim.BaseMask = (uint)(int)row["BaseMask"]; | ||
1352 | |||
1353 | // Vectors | ||
1354 | prim.OffsetPosition = new Vector3( | ||
1355 | (float)(double)row["PositionX"], | ||
1356 | (float)(double)row["PositionY"], | ||
1357 | (float)(double)row["PositionZ"] | ||
1358 | ); | ||
1359 | prim.GroupPosition = new Vector3( | ||
1360 | (float)(double)row["GroupPositionX"], | ||
1361 | (float)(double)row["GroupPositionY"], | ||
1362 | (float)(double)row["GroupPositionZ"] | ||
1363 | ); | ||
1364 | prim.Velocity = new Vector3( | ||
1365 | (float)(double)row["VelocityX"], | ||
1366 | (float)(double)row["VelocityY"], | ||
1367 | (float)(double)row["VelocityZ"] | ||
1368 | ); | ||
1369 | prim.AngularVelocity = new Vector3( | ||
1370 | (float)(double)row["AngularVelocityX"], | ||
1371 | (float)(double)row["AngularVelocityY"], | ||
1372 | (float)(double)row["AngularVelocityZ"] | ||
1373 | ); | ||
1374 | prim.Acceleration = new Vector3( | ||
1375 | (float)(double)row["AccelerationX"], | ||
1376 | (float)(double)row["AccelerationY"], | ||
1377 | (float)(double)row["AccelerationZ"] | ||
1378 | ); | ||
1379 | // quaternions | ||
1380 | prim.RotationOffset = new Quaternion( | ||
1381 | (float)(double)row["RotationX"], | ||
1382 | (float)(double)row["RotationY"], | ||
1383 | (float)(double)row["RotationZ"], | ||
1384 | (float)(double)row["RotationW"] | ||
1385 | ); | ||
1386 | prim.SitTargetPositionLL = new Vector3( | ||
1387 | (float)(double)row["SitTargetOffsetX"], | ||
1388 | (float)(double)row["SitTargetOffsetY"], | ||
1389 | (float)(double)row["SitTargetOffsetZ"] | ||
1390 | ); | ||
1391 | prim.SitTargetOrientationLL = new Quaternion( | ||
1392 | (float)(double)row["SitTargetOrientX"], | ||
1393 | (float)(double)row["SitTargetOrientY"], | ||
1394 | (float)(double)row["SitTargetOrientZ"], | ||
1395 | (float)(double)row["SitTargetOrientW"] | ||
1396 | ); | ||
1397 | |||
1398 | prim.PayPrice[0] = (int)row["PayPrice"]; | ||
1399 | prim.PayPrice[1] = (int)row["PayButton1"]; | ||
1400 | prim.PayPrice[2] = (int)row["PayButton2"]; | ||
1401 | prim.PayPrice[3] = (int)row["PayButton3"]; | ||
1402 | prim.PayPrice[4] = (int)row["PayButton4"]; | ||
1403 | |||
1404 | prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString()); | ||
1405 | prim.SoundGain = (float)(double)row["LoopedSoundGain"]; | ||
1406 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1407 | |||
1408 | if (!(row["TextureAnimation"] is DBNull)) | ||
1409 | prim.TextureAnimation = (byte[])row["TextureAnimation"]; | ||
1410 | if (!(row["ParticleSystem"] is DBNull)) | ||
1411 | prim.ParticleSystem = (byte[])row["ParticleSystem"]; | ||
1412 | |||
1413 | prim.AngularVelocity = new Vector3( | ||
1414 | (float)(double)row["OmegaX"], | ||
1415 | (float)(double)row["OmegaY"], | ||
1416 | (float)(double)row["OmegaZ"] | ||
1417 | ); | ||
1418 | |||
1419 | prim.SetCameraEyeOffset(new Vector3( | ||
1420 | (float)(double)row["CameraEyeOffsetX"], | ||
1421 | (float)(double)row["CameraEyeOffsetY"], | ||
1422 | (float)(double)row["CameraEyeOffsetZ"] | ||
1423 | )); | ||
1424 | |||
1425 | prim.SetCameraAtOffset(new Vector3( | ||
1426 | (float)(double)row["CameraAtOffsetX"], | ||
1427 | (float)(double)row["CameraAtOffsetY"], | ||
1428 | (float)(double)row["CameraAtOffsetZ"] | ||
1429 | )); | ||
1430 | |||
1431 | prim.SetForceMouselook((sbyte)row["ForceMouselook"] != 0); | ||
1432 | prim.ScriptAccessPin = (int)row["ScriptAccessPin"]; | ||
1433 | prim.AllowedDrop = ((sbyte)row["AllowedDrop"] != 0); | ||
1434 | prim.DIE_AT_EDGE = ((sbyte)row["DieAtEdge"] != 0); | ||
1435 | |||
1436 | prim.SalePrice = (int)row["SalePrice"]; | ||
1437 | prim.ObjectSaleType = unchecked((byte)(sbyte)row["SaleType"]); | ||
1438 | |||
1439 | prim.Material = unchecked((byte)(sbyte)row["Material"]); | ||
1440 | |||
1441 | if (!(row["ClickAction"] is DBNull)) | ||
1442 | prim.ClickAction = unchecked((byte)(sbyte)row["ClickAction"]); | ||
1443 | |||
1444 | prim.CollisionSound = DBGuid.FromDB(row["CollisionSound"]); | ||
1445 | prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"]; | ||
1446 | |||
1447 | prim.PassTouches = ((sbyte)row["PassTouches"] != 0); | ||
1448 | prim.PassCollisions = ((sbyte)row["PassCollisions"] != 0); | ||
1449 | prim.LinkNum = (int)row["LinkNumber"]; | ||
1450 | |||
1451 | if (!(row["MediaURL"] is System.DBNull)) | ||
1452 | prim.MediaUrl = (string)row["MediaURL"]; | ||
1453 | |||
1454 | if (!(row["AttachedPosX"] is System.DBNull)) | ||
1455 | { | ||
1456 | prim.AttachedPos = new Vector3( | ||
1457 | (float)(double)row["AttachedPosX"], | ||
1458 | (float)(double)row["AttachedPosY"], | ||
1459 | (float)(double)row["AttachedPosZ"] | ||
1460 | ); | ||
1461 | } | ||
1462 | |||
1463 | if (!(row["DynAttrs"] is System.DBNull)) | ||
1464 | prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); | ||
1465 | else | ||
1466 | prim.DynAttrs = new DAMap(); | ||
1467 | |||
1468 | if (!(row["KeyframeMotion"] is DBNull)) | ||
1469 | { | ||
1470 | Byte[] data = (byte[])row["KeyframeMotion"]; | ||
1471 | if (data.Length > 0) | ||
1472 | prim.KeyframeMotion = KeyframeMotion.FromData(null, data); | ||
1473 | else | ||
1474 | prim.KeyframeMotion = null; | ||
1475 | } | ||
1476 | else | ||
1477 | { | ||
1478 | prim.KeyframeMotion = null; | ||
1479 | } | ||
1480 | |||
1481 | prim.PhysicsShapeType = (byte)Convert.ToInt32(row["PhysicsShapeType"].ToString()); | ||
1482 | prim.Density = (float)(double)row["Density"]; | ||
1483 | prim.GravityModifier = (float)(double)row["GravityModifier"]; | ||
1484 | prim.Friction = (float)(double)row["Friction"]; | ||
1485 | prim.Restitution = (float)(double)row["Restitution"]; | ||
1486 | prim.RotationAxisLocks = (byte)Convert.ToInt32(row["RotationAxisLocks"].ToString()); | ||
1487 | |||
1488 | SOPVehicle vehicle = null; | ||
1489 | |||
1490 | if (row["Vehicle"].ToString() != String.Empty) | ||
1491 | { | ||
1492 | vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString()); | ||
1493 | if (vehicle != null) | ||
1494 | prim.VehicleParams = vehicle; | ||
1495 | } | ||
1496 | |||
1497 | PhysicsInertiaData pdata = null; | ||
1498 | if (row["PhysInertia"].ToString() != String.Empty) | ||
1499 | pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); | ||
1500 | prim.PhysicsInertia = pdata; | ||
1501 | |||
1502 | return prim; | ||
1503 | } | ||
1504 | |||
1505 | /// <summary> | ||
1506 | /// Build a prim inventory item from the persisted data. | ||
1507 | /// </summary> | ||
1508 | /// <param name="row"></param> | ||
1509 | /// <returns></returns> | ||
1510 | private static TaskInventoryItem BuildItem(IDataReader row) | ||
1511 | { | ||
1512 | try | ||
1513 | { | ||
1514 | TaskInventoryItem taskItem = new TaskInventoryItem(); | ||
1515 | |||
1516 | taskItem.ItemID = DBGuid.FromDB(row["itemID"]); | ||
1517 | taskItem.ParentPartID = DBGuid.FromDB(row["primID"]); | ||
1518 | taskItem.AssetID = DBGuid.FromDB(row["assetID"]); | ||
1519 | taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]); | ||
1520 | |||
1521 | taskItem.InvType = Convert.ToInt32(row["invType"]); | ||
1522 | taskItem.Type = Convert.ToInt32(row["assetType"]); | ||
1523 | |||
1524 | taskItem.Name = (String)row["name"]; | ||
1525 | taskItem.Description = (String)row["description"]; | ||
1526 | taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); | ||
1527 | taskItem.CreatorIdentification = (String)row["creatorID"]; | ||
1528 | taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]); | ||
1529 | taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]); | ||
1530 | taskItem.GroupID = DBGuid.FromDB(row["groupID"]); | ||
1531 | |||
1532 | taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); | ||
1533 | taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); | ||
1534 | taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); | ||
1535 | taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); | ||
1536 | taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); | ||
1537 | taskItem.Flags = Convert.ToUInt32(row["flags"]); | ||
1538 | |||
1539 | return taskItem; | ||
1540 | } | ||
1541 | catch | ||
1542 | { | ||
1543 | m_log.ErrorFormat("[MYSQL DB]: Error reading task inventory: itemID was {0}, primID was {1}", row["itemID"].ToString(), row["primID"].ToString()); | ||
1544 | throw; | ||
1545 | } | ||
1546 | } | ||
1547 | |||
1548 | private static RegionSettings BuildRegionSettings(IDataReader row) | ||
1549 | { | ||
1550 | RegionSettings newSettings = new RegionSettings(); | ||
1551 | |||
1552 | newSettings.RegionUUID = DBGuid.FromDB(row["regionUUID"]); | ||
1553 | newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); | ||
1554 | newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); | ||
1555 | newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); | ||
1556 | newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); | ||
1557 | newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); | ||
1558 | newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); | ||
1559 | newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); | ||
1560 | newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); | ||
1561 | newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); | ||
1562 | newSettings.Maturity = Convert.ToInt32(row["maturity"]); | ||
1563 | newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); | ||
1564 | newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); | ||
1565 | newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); | ||
1566 | newSettings.TerrainTexture1 = DBGuid.FromDB(row["terrain_texture_1"]); | ||
1567 | newSettings.TerrainTexture2 = DBGuid.FromDB(row["terrain_texture_2"]); | ||
1568 | newSettings.TerrainTexture3 = DBGuid.FromDB(row["terrain_texture_3"]); | ||
1569 | newSettings.TerrainTexture4 = DBGuid.FromDB(row["terrain_texture_4"]); | ||
1570 | newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); | ||
1571 | newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); | ||
1572 | newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); | ||
1573 | newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); | ||
1574 | newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); | ||
1575 | newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); | ||
1576 | newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); | ||
1577 | newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); | ||
1578 | newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); | ||
1579 | newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); | ||
1580 | newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); | ||
1581 | newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); | ||
1582 | newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]); | ||
1583 | newSettings.SunVector = new Vector3 ( | ||
1584 | Convert.ToSingle(row["sunvectorx"]), | ||
1585 | Convert.ToSingle(row["sunvectory"]), | ||
1586 | Convert.ToSingle(row["sunvectorz"]) | ||
1587 | ); | ||
1588 | newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); | ||
1589 | newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); | ||
1590 | newSettings.Covenant = DBGuid.FromDB(row["covenant"]); | ||
1591 | newSettings.CovenantChangedDateTime = Convert.ToInt32(row["covenant_datetime"]); | ||
1592 | newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); | ||
1593 | |||
1594 | if (row["loaded_creation_id"] is DBNull) | ||
1595 | newSettings.LoadedCreationID = ""; | ||
1596 | else | ||
1597 | newSettings.LoadedCreationID = (String) row["loaded_creation_id"]; | ||
1598 | |||
1599 | newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]); | ||
1600 | newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]); | ||
1601 | newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]); | ||
1602 | |||
1603 | newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]); | ||
1604 | newSettings.Casino = Convert.ToBoolean(row["casino"]); | ||
1605 | |||
1606 | return newSettings; | ||
1607 | } | ||
1608 | |||
1609 | /// <summary> | ||
1610 | /// | ||
1611 | /// </summary> | ||
1612 | /// <param name="row"></param> | ||
1613 | /// <returns></returns> | ||
1614 | private static LandData BuildLandData(IDataReader row) | ||
1615 | { | ||
1616 | LandData newData = new LandData(); | ||
1617 | |||
1618 | newData.GlobalID = DBGuid.FromDB(row["UUID"]); | ||
1619 | newData.LocalID = Convert.ToInt32(row["LocalLandID"]); | ||
1620 | |||
1621 | // Bitmap is a byte[512] | ||
1622 | newData.Bitmap = (Byte[]) row["Bitmap"]; | ||
1623 | |||
1624 | newData.Name = (String) row["Name"]; | ||
1625 | newData.Description = (String) row["Description"]; | ||
1626 | newData.OwnerID = DBGuid.FromDB(row["OwnerUUID"]); | ||
1627 | newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); | ||
1628 | newData.Area = Convert.ToInt32(row["Area"]); | ||
1629 | newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented | ||
1630 | newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]); | ||
1631 | //Enum libsecondlife.Parcel.ParcelCategory | ||
1632 | newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); | ||
1633 | newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); | ||
1634 | newData.GroupID = DBGuid.FromDB(row["GroupUUID"]); | ||
1635 | newData.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
1636 | newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]); | ||
1637 | //Enum. libsecondlife.Parcel.ParcelStatus | ||
1638 | newData.Flags = Convert.ToUInt32(row["LandFlags"]); | ||
1639 | newData.LandingType = Convert.ToByte(row["LandingType"]); | ||
1640 | newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); | ||
1641 | newData.MediaID = DBGuid.FromDB(row["MediaTextureUUID"]); | ||
1642 | newData.MediaURL = (String) row["MediaURL"]; | ||
1643 | newData.MusicURL = (String) row["MusicURL"]; | ||
1644 | newData.PassHours = Convert.ToSingle(row["PassHours"]); | ||
1645 | newData.PassPrice = Convert.ToInt32(row["PassPrice"]); | ||
1646 | UUID authedbuyer = UUID.Zero; | ||
1647 | UUID snapshotID = UUID.Zero; | ||
1648 | |||
1649 | UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer); | ||
1650 | UUID.TryParse((string)row["SnapshotUUID"], out snapshotID); | ||
1651 | newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); | ||
1652 | newData.Dwell = Convert.ToSingle(row["Dwell"]); | ||
1653 | |||
1654 | newData.AuthBuyerID = authedbuyer; | ||
1655 | newData.SnapshotID = snapshotID; | ||
1656 | try | ||
1657 | { | ||
1658 | newData.UserLocation = | ||
1659 | new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), | ||
1660 | Convert.ToSingle(row["UserLocationZ"])); | ||
1661 | newData.UserLookAt = | ||
1662 | new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), | ||
1663 | Convert.ToSingle(row["UserLookAtZ"])); | ||
1664 | } | ||
1665 | catch (InvalidCastException) | ||
1666 | { | ||
1667 | newData.UserLocation = Vector3.Zero; | ||
1668 | newData.UserLookAt = Vector3.Zero; | ||
1669 | m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); | ||
1670 | } | ||
1671 | |||
1672 | newData.MediaDescription = (string) row["MediaDescription"]; | ||
1673 | newData.MediaType = (string) row["MediaType"]; | ||
1674 | newData.MediaWidth = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[0]); | ||
1675 | newData.MediaHeight = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[1]); | ||
1676 | newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); | ||
1677 | newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); | ||
1678 | newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); | ||
1679 | |||
1680 | newData.ParcelAccessList = new List<LandAccessEntry>(); | ||
1681 | |||
1682 | if (!(row["SeeAVs"] is System.DBNull)) | ||
1683 | newData.SeeAVs = Convert.ToInt32(row["SeeAVs"]) != 0 ? true : false; | ||
1684 | if (!(row["AnyAVSounds"] is System.DBNull)) | ||
1685 | newData.AnyAVSounds = Convert.ToInt32(row["AnyAVSounds"]) != 0 ? true : false; | ||
1686 | if (!(row["GroupAVSounds"] is System.DBNull)) | ||
1687 | newData.GroupAVSounds = Convert.ToInt32(row["GroupAVSounds"]) != 0 ? true : false; | ||
1688 | |||
1689 | return newData; | ||
1690 | } | ||
1691 | |||
1692 | /// <summary> | ||
1693 | /// | ||
1694 | /// </summary> | ||
1695 | /// <param name="row"></param> | ||
1696 | /// <returns></returns> | ||
1697 | private static LandAccessEntry BuildLandAccessData(IDataReader row) | ||
1698 | { | ||
1699 | LandAccessEntry entry = new LandAccessEntry(); | ||
1700 | entry.AgentID = DBGuid.FromDB(row["AccessUUID"]); | ||
1701 | entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]); | ||
1702 | entry.Expires = Convert.ToInt32(row["Expires"]); | ||
1703 | return entry; | ||
1704 | } | ||
1705 | |||
1706 | /// <summary> | ||
1707 | /// Fill the prim command with prim values | ||
1708 | /// </summary> | ||
1709 | /// <param name="row"></param> | ||
1710 | /// <param name="prim"></param> | ||
1711 | /// <param name="sceneGroupID"></param> | ||
1712 | /// <param name="regionUUID"></param> | ||
1713 | private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) | ||
1714 | { | ||
1715 | cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); | ||
1716 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1717 | cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate); | ||
1718 | cmd.Parameters.AddWithValue("Name", prim.Name); | ||
1719 | cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString()); | ||
1720 | // the UUID of the root part for this SceneObjectGroup | ||
1721 | // various text fields | ||
1722 | cmd.Parameters.AddWithValue("Text", prim.Text); | ||
1723 | cmd.Parameters.AddWithValue("ColorR", prim.Color.R); | ||
1724 | cmd.Parameters.AddWithValue("ColorG", prim.Color.G); | ||
1725 | cmd.Parameters.AddWithValue("ColorB", prim.Color.B); | ||
1726 | cmd.Parameters.AddWithValue("ColorA", prim.Color.A); | ||
1727 | cmd.Parameters.AddWithValue("Description", prim.Description); | ||
1728 | cmd.Parameters.AddWithValue("SitName", prim.SitName); | ||
1729 | cmd.Parameters.AddWithValue("TouchName", prim.TouchName); | ||
1730 | // permissions | ||
1731 | cmd.Parameters.AddWithValue("ObjectFlags", (uint)prim.Flags); | ||
1732 | cmd.Parameters.AddWithValue("CreatorID", prim.CreatorIdentification.ToString()); | ||
1733 | cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); | ||
1734 | cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); | ||
1735 | cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); | ||
1736 | cmd.Parameters.AddWithValue("RezzerID", prim.RezzerID.ToString()); | ||
1737 | cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); | ||
1738 | cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); | ||
1739 | cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); | ||
1740 | cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask); | ||
1741 | cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask); | ||
1742 | // vectors | ||
1743 | cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X); | ||
1744 | cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y); | ||
1745 | cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z); | ||
1746 | cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X); | ||
1747 | cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y); | ||
1748 | cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z); | ||
1749 | cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X); | ||
1750 | cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y); | ||
1751 | cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z); | ||
1752 | cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X); | ||
1753 | cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y); | ||
1754 | cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z); | ||
1755 | cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X); | ||
1756 | cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y); | ||
1757 | cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z); | ||
1758 | // quaternions | ||
1759 | cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X); | ||
1760 | cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y); | ||
1761 | cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z); | ||
1762 | cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W); | ||
1763 | |||
1764 | // Sit target | ||
1765 | Vector3 sitTargetPos = prim.SitTargetPositionLL; | ||
1766 | cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X); | ||
1767 | cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y); | ||
1768 | cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z); | ||
1769 | |||
1770 | Quaternion sitTargetOrient = prim.SitTargetOrientationLL; | ||
1771 | cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W); | ||
1772 | cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X); | ||
1773 | cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y); | ||
1774 | cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z); | ||
1775 | |||
1776 | cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]); | ||
1777 | cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]); | ||
1778 | cmd.Parameters.AddWithValue("PayButton2", prim.PayPrice[2]); | ||
1779 | cmd.Parameters.AddWithValue("PayButton3", prim.PayPrice[3]); | ||
1780 | cmd.Parameters.AddWithValue("PayButton4", prim.PayPrice[4]); | ||
1781 | |||
1782 | if ((prim.SoundFlags & 1) != 0) // Looped | ||
1783 | { | ||
1784 | cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString()); | ||
1785 | cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain); | ||
1786 | } | ||
1787 | else | ||
1788 | { | ||
1789 | cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero); | ||
1790 | cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f); | ||
1791 | } | ||
1792 | |||
1793 | cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation); | ||
1794 | cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem); | ||
1795 | |||
1796 | cmd.Parameters.AddWithValue("OmegaX", (double)prim.AngularVelocity.X); | ||
1797 | cmd.Parameters.AddWithValue("OmegaY", (double)prim.AngularVelocity.Y); | ||
1798 | cmd.Parameters.AddWithValue("OmegaZ", (double)prim.AngularVelocity.Z); | ||
1799 | |||
1800 | cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X); | ||
1801 | cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y); | ||
1802 | cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z); | ||
1803 | |||
1804 | cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X); | ||
1805 | cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y); | ||
1806 | cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z); | ||
1807 | |||
1808 | if (prim.GetForceMouselook()) | ||
1809 | cmd.Parameters.AddWithValue("ForceMouselook", 1); | ||
1810 | else | ||
1811 | cmd.Parameters.AddWithValue("ForceMouselook", 0); | ||
1812 | |||
1813 | cmd.Parameters.AddWithValue("ScriptAccessPin", prim.ScriptAccessPin); | ||
1814 | |||
1815 | if (prim.AllowedDrop) | ||
1816 | cmd.Parameters.AddWithValue("AllowedDrop", 1); | ||
1817 | else | ||
1818 | cmd.Parameters.AddWithValue("AllowedDrop", 0); | ||
1819 | |||
1820 | if (prim.DIE_AT_EDGE) | ||
1821 | cmd.Parameters.AddWithValue("DieAtEdge", 1); | ||
1822 | else | ||
1823 | cmd.Parameters.AddWithValue("DieAtEdge", 0); | ||
1824 | |||
1825 | cmd.Parameters.AddWithValue("SalePrice", prim.SalePrice); | ||
1826 | cmd.Parameters.AddWithValue("SaleType", unchecked((sbyte)(prim.ObjectSaleType))); | ||
1827 | |||
1828 | byte clickAction = prim.ClickAction; | ||
1829 | cmd.Parameters.AddWithValue("ClickAction", unchecked((sbyte)(clickAction))); | ||
1830 | |||
1831 | cmd.Parameters.AddWithValue("Material", unchecked((sbyte)(prim.Material))); | ||
1832 | |||
1833 | cmd.Parameters.AddWithValue("CollisionSound", prim.CollisionSound.ToString()); | ||
1834 | cmd.Parameters.AddWithValue("CollisionSoundVolume", prim.CollisionSoundVolume); | ||
1835 | |||
1836 | if (prim.PassTouches) | ||
1837 | cmd.Parameters.AddWithValue("PassTouches", 1); | ||
1838 | else | ||
1839 | cmd.Parameters.AddWithValue("PassTouches", 0); | ||
1840 | |||
1841 | if (prim.PassCollisions) | ||
1842 | cmd.Parameters.AddWithValue("PassCollisions", 1); | ||
1843 | else | ||
1844 | cmd.Parameters.AddWithValue("PassCollisions", 0); | ||
1845 | |||
1846 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); | ||
1847 | cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); | ||
1848 | if (prim.AttachedPos != null) | ||
1849 | { | ||
1850 | cmd.Parameters.AddWithValue("AttachedPosX", (double)prim.AttachedPos.X); | ||
1851 | cmd.Parameters.AddWithValue("AttachedPosY", (double)prim.AttachedPos.Y); | ||
1852 | cmd.Parameters.AddWithValue("AttachedPosZ", (double)prim.AttachedPos.Z); | ||
1853 | } | ||
1854 | |||
1855 | if (prim.KeyframeMotion != null) | ||
1856 | cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize()); | ||
1857 | else | ||
1858 | cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); | ||
1859 | |||
1860 | if (prim.PhysicsInertia != null) | ||
1861 | cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2()); | ||
1862 | else | ||
1863 | cmd.Parameters.AddWithValue("PhysInertia", String.Empty); | ||
1864 | |||
1865 | if (prim.VehicleParams != null) | ||
1866 | cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); | ||
1867 | else | ||
1868 | cmd.Parameters.AddWithValue("Vehicle", String.Empty); | ||
1869 | |||
1870 | if (prim.DynAttrs.CountNamespaces > 0) | ||
1871 | cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml()); | ||
1872 | else | ||
1873 | cmd.Parameters.AddWithValue("DynAttrs", null); | ||
1874 | |||
1875 | cmd.Parameters.AddWithValue("PhysicsShapeType", prim.PhysicsShapeType); | ||
1876 | cmd.Parameters.AddWithValue("Density", (double)prim.Density); | ||
1877 | cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier); | ||
1878 | cmd.Parameters.AddWithValue("Friction", (double)prim.Friction); | ||
1879 | cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution); | ||
1880 | cmd.Parameters.AddWithValue("RotationAxisLocks", prim.RotationAxisLocks); | ||
1881 | } | ||
1882 | |||
1883 | /// <summary> | ||
1884 | /// | ||
1885 | /// </summary> | ||
1886 | /// <param name="row"></param> | ||
1887 | /// <param name="taskItem"></param> | ||
1888 | private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem) | ||
1889 | { | ||
1890 | cmd.Parameters.AddWithValue("itemID", taskItem.ItemID); | ||
1891 | cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID); | ||
1892 | cmd.Parameters.AddWithValue("assetID", taskItem.AssetID); | ||
1893 | cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID); | ||
1894 | |||
1895 | cmd.Parameters.AddWithValue("invType", taskItem.InvType); | ||
1896 | cmd.Parameters.AddWithValue("assetType", taskItem.Type); | ||
1897 | |||
1898 | cmd.Parameters.AddWithValue("name", taskItem.Name); | ||
1899 | cmd.Parameters.AddWithValue("description", taskItem.Description); | ||
1900 | cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate); | ||
1901 | cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorIdentification); | ||
1902 | cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID); | ||
1903 | cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID); | ||
1904 | cmd.Parameters.AddWithValue("groupID", taskItem.GroupID); | ||
1905 | cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions); | ||
1906 | cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions); | ||
1907 | cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions); | ||
1908 | cmd.Parameters.AddWithValue("everyonePermissions", taskItem.EveryonePermissions); | ||
1909 | cmd.Parameters.AddWithValue("groupPermissions", taskItem.GroupPermissions); | ||
1910 | cmd.Parameters.AddWithValue("flags", taskItem.Flags); | ||
1911 | } | ||
1912 | |||
1913 | /// <summary> | ||
1914 | /// | ||
1915 | /// </summary> | ||
1916 | private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings settings) | ||
1917 | { | ||
1918 | cmd.Parameters.AddWithValue("RegionUUID", settings.RegionUUID.ToString()); | ||
1919 | cmd.Parameters.AddWithValue("BlockTerraform", settings.BlockTerraform); | ||
1920 | cmd.Parameters.AddWithValue("BlockFly", settings.BlockFly); | ||
1921 | cmd.Parameters.AddWithValue("AllowDamage", settings.AllowDamage); | ||
1922 | cmd.Parameters.AddWithValue("RestrictPushing", settings.RestrictPushing); | ||
1923 | cmd.Parameters.AddWithValue("AllowLandResell", settings.AllowLandResell); | ||
1924 | cmd.Parameters.AddWithValue("AllowLandJoinDivide", settings.AllowLandJoinDivide); | ||
1925 | cmd.Parameters.AddWithValue("BlockShowInSearch", settings.BlockShowInSearch); | ||
1926 | cmd.Parameters.AddWithValue("AgentLimit", settings.AgentLimit); | ||
1927 | cmd.Parameters.AddWithValue("ObjectBonus", settings.ObjectBonus); | ||
1928 | cmd.Parameters.AddWithValue("Maturity", settings.Maturity); | ||
1929 | cmd.Parameters.AddWithValue("DisableScripts", settings.DisableScripts); | ||
1930 | cmd.Parameters.AddWithValue("DisableCollisions", settings.DisableCollisions); | ||
1931 | cmd.Parameters.AddWithValue("DisablePhysics", settings.DisablePhysics); | ||
1932 | cmd.Parameters.AddWithValue("TerrainTexture1", settings.TerrainTexture1.ToString()); | ||
1933 | cmd.Parameters.AddWithValue("TerrainTexture2", settings.TerrainTexture2.ToString()); | ||
1934 | cmd.Parameters.AddWithValue("TerrainTexture3", settings.TerrainTexture3.ToString()); | ||
1935 | cmd.Parameters.AddWithValue("TerrainTexture4", settings.TerrainTexture4.ToString()); | ||
1936 | cmd.Parameters.AddWithValue("Elevation1NW", settings.Elevation1NW); | ||
1937 | cmd.Parameters.AddWithValue("Elevation2NW", settings.Elevation2NW); | ||
1938 | cmd.Parameters.AddWithValue("Elevation1NE", settings.Elevation1NE); | ||
1939 | cmd.Parameters.AddWithValue("Elevation2NE", settings.Elevation2NE); | ||
1940 | cmd.Parameters.AddWithValue("Elevation1SE", settings.Elevation1SE); | ||
1941 | cmd.Parameters.AddWithValue("Elevation2SE", settings.Elevation2SE); | ||
1942 | cmd.Parameters.AddWithValue("Elevation1SW", settings.Elevation1SW); | ||
1943 | cmd.Parameters.AddWithValue("Elevation2SW", settings.Elevation2SW); | ||
1944 | cmd.Parameters.AddWithValue("WaterHeight", settings.WaterHeight); | ||
1945 | cmd.Parameters.AddWithValue("TerrainRaiseLimit", settings.TerrainRaiseLimit); | ||
1946 | cmd.Parameters.AddWithValue("TerrainLowerLimit", settings.TerrainLowerLimit); | ||
1947 | cmd.Parameters.AddWithValue("UseEstateSun", settings.UseEstateSun); | ||
1948 | cmd.Parameters.AddWithValue("Sandbox", settings.Sandbox); | ||
1949 | cmd.Parameters.AddWithValue("SunVectorX", settings.SunVector.X); | ||
1950 | cmd.Parameters.AddWithValue("SunVectorY", settings.SunVector.Y); | ||
1951 | cmd.Parameters.AddWithValue("SunVectorZ", settings.SunVector.Z); | ||
1952 | cmd.Parameters.AddWithValue("FixedSun", settings.FixedSun); | ||
1953 | cmd.Parameters.AddWithValue("SunPosition", settings.SunPosition); | ||
1954 | cmd.Parameters.AddWithValue("Covenant", settings.Covenant.ToString()); | ||
1955 | cmd.Parameters.AddWithValue("CovenantChangedDateTime", settings.CovenantChangedDateTime); | ||
1956 | cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); | ||
1957 | cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); | ||
1958 | cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID); | ||
1959 | cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch); | ||
1960 | cmd.Parameters.AddWithValue("casino", settings.Casino); | ||
1961 | |||
1962 | cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID); | ||
1963 | cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject); | ||
1964 | } | ||
1965 | |||
1966 | /// <summary> | ||
1967 | /// | ||
1968 | /// </summary> | ||
1969 | /// <param name="row"></param> | ||
1970 | /// <param name="land"></param> | ||
1971 | /// <param name="regionUUID"></param> | ||
1972 | private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID regionUUID) | ||
1973 | { | ||
1974 | cmd.Parameters.AddWithValue("UUID", land.GlobalID.ToString()); | ||
1975 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1976 | cmd.Parameters.AddWithValue("LocalLandID", land.LocalID); | ||
1977 | |||
1978 | // Bitmap is a byte[512] | ||
1979 | cmd.Parameters.AddWithValue("Bitmap", land.Bitmap); | ||
1980 | |||
1981 | cmd.Parameters.AddWithValue("Name", land.Name); | ||
1982 | cmd.Parameters.AddWithValue("Description", land.Description); | ||
1983 | cmd.Parameters.AddWithValue("OwnerUUID", land.OwnerID.ToString()); | ||
1984 | cmd.Parameters.AddWithValue("IsGroupOwned", land.IsGroupOwned); | ||
1985 | cmd.Parameters.AddWithValue("Area", land.Area); | ||
1986 | cmd.Parameters.AddWithValue("AuctionID", land.AuctionID); //Unemplemented | ||
1987 | cmd.Parameters.AddWithValue("Category", land.Category); //Enum libsecondlife.Parcel.ParcelCategory | ||
1988 | cmd.Parameters.AddWithValue("ClaimDate", land.ClaimDate); | ||
1989 | cmd.Parameters.AddWithValue("ClaimPrice", land.ClaimPrice); | ||
1990 | cmd.Parameters.AddWithValue("GroupUUID", land.GroupID.ToString()); | ||
1991 | cmd.Parameters.AddWithValue("SalePrice", land.SalePrice); | ||
1992 | cmd.Parameters.AddWithValue("LandStatus", land.Status); //Enum. libsecondlife.Parcel.ParcelStatus | ||
1993 | cmd.Parameters.AddWithValue("LandFlags", land.Flags); | ||
1994 | cmd.Parameters.AddWithValue("LandingType", land.LandingType); | ||
1995 | cmd.Parameters.AddWithValue("MediaAutoScale", land.MediaAutoScale); | ||
1996 | cmd.Parameters.AddWithValue("MediaTextureUUID", land.MediaID.ToString()); | ||
1997 | cmd.Parameters.AddWithValue("MediaURL", land.MediaURL); | ||
1998 | cmd.Parameters.AddWithValue("MusicURL", land.MusicURL); | ||
1999 | cmd.Parameters.AddWithValue("PassHours", land.PassHours); | ||
2000 | cmd.Parameters.AddWithValue("PassPrice", land.PassPrice); | ||
2001 | cmd.Parameters.AddWithValue("SnapshotUUID", land.SnapshotID.ToString()); | ||
2002 | cmd.Parameters.AddWithValue("UserLocationX", land.UserLocation.X); | ||
2003 | cmd.Parameters.AddWithValue("UserLocationY", land.UserLocation.Y); | ||
2004 | cmd.Parameters.AddWithValue("UserLocationZ", land.UserLocation.Z); | ||
2005 | cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X); | ||
2006 | cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y); | ||
2007 | cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); | ||
2008 | cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); | ||
2009 | cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); | ||
2010 | cmd.Parameters.AddWithValue("Dwell", land.Dwell); | ||
2011 | cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription); | ||
2012 | cmd.Parameters.AddWithValue("MediaType", land.MediaType); | ||
2013 | cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth); | ||
2014 | cmd.Parameters.AddWithValue("MediaHeight", land.MediaHeight); | ||
2015 | cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop); | ||
2016 | cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic); | ||
2017 | cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia); | ||
2018 | cmd.Parameters.AddWithValue("SeeAVs", land.SeeAVs ? 1 : 0); | ||
2019 | cmd.Parameters.AddWithValue("AnyAVSounds", land.AnyAVSounds ? 1 : 0); | ||
2020 | cmd.Parameters.AddWithValue("GroupAVSounds", land.GroupAVSounds ? 1 : 0); | ||
2021 | |||
2022 | } | ||
2023 | |||
2024 | /// <summary> | ||
2025 | /// | ||
2026 | /// </summary> | ||
2027 | /// <param name="row"></param> | ||
2028 | /// <param name="entry"></param> | ||
2029 | /// <param name="parcelID"></param> | ||
2030 | private static void FillLandAccessCommand(MySqlCommand cmd, LandAccessEntry entry, UUID parcelID) | ||
2031 | { | ||
2032 | cmd.Parameters.AddWithValue("LandUUID", parcelID.ToString()); | ||
2033 | cmd.Parameters.AddWithValue("AccessUUID", entry.AgentID.ToString()); | ||
2034 | cmd.Parameters.AddWithValue("Flags", entry.Flags); | ||
2035 | cmd.Parameters.AddWithValue("Expires", entry.Expires.ToString()); | ||
2036 | } | ||
2037 | |||
2038 | /// <summary> | ||
2039 | /// | ||
2040 | /// </summary> | ||
2041 | /// <param name="row"></param> | ||
2042 | /// <returns></returns> | ||
2043 | private PrimitiveBaseShape BuildShape(IDataReader row) | ||
2044 | { | ||
2045 | PrimitiveBaseShape s = new PrimitiveBaseShape(); | ||
2046 | s.Scale = new Vector3( | ||
2047 | (float)(double)row["ScaleX"], | ||
2048 | (float)(double)row["ScaleY"], | ||
2049 | (float)(double)row["ScaleZ"] | ||
2050 | ); | ||
2051 | // paths | ||
2052 | s.PCode = (byte)(int)row["PCode"]; | ||
2053 | s.PathBegin = (ushort)(int)row["PathBegin"]; | ||
2054 | s.PathEnd = (ushort)(int)row["PathEnd"]; | ||
2055 | s.PathScaleX = (byte)(int)row["PathScaleX"]; | ||
2056 | s.PathScaleY = (byte)(int)row["PathScaleY"]; | ||
2057 | s.PathShearX = (byte)(int)row["PathShearX"]; | ||
2058 | s.PathShearY = (byte)(int)row["PathShearY"]; | ||
2059 | s.PathSkew = (sbyte)(int)row["PathSkew"]; | ||
2060 | s.PathCurve = (byte)(int)row["PathCurve"]; | ||
2061 | s.PathRadiusOffset = (sbyte)(int)row["PathRadiusOffset"]; | ||
2062 | s.PathRevolutions = (byte)(int)row["PathRevolutions"]; | ||
2063 | s.PathTaperX = (sbyte)(int)row["PathTaperX"]; | ||
2064 | s.PathTaperY = (sbyte)(int)row["PathTaperY"]; | ||
2065 | s.PathTwist = (sbyte)(int)row["PathTwist"]; | ||
2066 | s.PathTwistBegin = (sbyte)(int)row["PathTwistBegin"]; | ||
2067 | // profile | ||
2068 | s.ProfileBegin = (ushort)(int)row["ProfileBegin"]; | ||
2069 | s.ProfileEnd = (ushort)(int)row["ProfileEnd"]; | ||
2070 | s.ProfileCurve = (byte)(int)row["ProfileCurve"]; | ||
2071 | s.ProfileHollow = (ushort)(int)row["ProfileHollow"]; | ||
2072 | s.TextureEntry = (byte[])row["Texture"]; | ||
2073 | |||
2074 | s.ExtraParams = (byte[])row["ExtraParams"]; | ||
2075 | |||
2076 | s.State = (byte)(int)row["State"]; | ||
2077 | s.LastAttachPoint = (byte)(int)row["LastAttachPoint"]; | ||
2078 | |||
2079 | if (!(row["Media"] is System.DBNull)) | ||
2080 | s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); | ||
2081 | |||
2082 | return s; | ||
2083 | } | ||
2084 | |||
2085 | /// <summary> | ||
2086 | /// | ||
2087 | /// </summary> | ||
2088 | /// <param name="row"></param> | ||
2089 | /// <param name="prim"></param> | ||
2090 | private void FillShapeCommand(MySqlCommand cmd, SceneObjectPart prim) | ||
2091 | { | ||
2092 | PrimitiveBaseShape s = prim.Shape; | ||
2093 | cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); | ||
2094 | // shape is an enum | ||
2095 | cmd.Parameters.AddWithValue("Shape", 0); | ||
2096 | // vectors | ||
2097 | cmd.Parameters.AddWithValue("ScaleX", (double)s.Scale.X); | ||
2098 | cmd.Parameters.AddWithValue("ScaleY", (double)s.Scale.Y); | ||
2099 | cmd.Parameters.AddWithValue("ScaleZ", (double)s.Scale.Z); | ||
2100 | // paths | ||
2101 | cmd.Parameters.AddWithValue("PCode", s.PCode); | ||
2102 | cmd.Parameters.AddWithValue("PathBegin", s.PathBegin); | ||
2103 | cmd.Parameters.AddWithValue("PathEnd", s.PathEnd); | ||
2104 | cmd.Parameters.AddWithValue("PathScaleX", s.PathScaleX); | ||
2105 | cmd.Parameters.AddWithValue("PathScaleY", s.PathScaleY); | ||
2106 | cmd.Parameters.AddWithValue("PathShearX", s.PathShearX); | ||
2107 | cmd.Parameters.AddWithValue("PathShearY", s.PathShearY); | ||
2108 | cmd.Parameters.AddWithValue("PathSkew", s.PathSkew); | ||
2109 | cmd.Parameters.AddWithValue("PathCurve", s.PathCurve); | ||
2110 | cmd.Parameters.AddWithValue("PathRadiusOffset", s.PathRadiusOffset); | ||
2111 | cmd.Parameters.AddWithValue("PathRevolutions", s.PathRevolutions); | ||
2112 | cmd.Parameters.AddWithValue("PathTaperX", s.PathTaperX); | ||
2113 | cmd.Parameters.AddWithValue("PathTaperY", s.PathTaperY); | ||
2114 | cmd.Parameters.AddWithValue("PathTwist", s.PathTwist); | ||
2115 | cmd.Parameters.AddWithValue("PathTwistBegin", s.PathTwistBegin); | ||
2116 | // profile | ||
2117 | cmd.Parameters.AddWithValue("ProfileBegin", s.ProfileBegin); | ||
2118 | cmd.Parameters.AddWithValue("ProfileEnd", s.ProfileEnd); | ||
2119 | cmd.Parameters.AddWithValue("ProfileCurve", s.ProfileCurve); | ||
2120 | cmd.Parameters.AddWithValue("ProfileHollow", s.ProfileHollow); | ||
2121 | cmd.Parameters.AddWithValue("Texture", s.TextureEntry); | ||
2122 | cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); | ||
2123 | cmd.Parameters.AddWithValue("State", s.State); | ||
2124 | cmd.Parameters.AddWithValue("LastAttachPoint", s.LastAttachPoint); | ||
2125 | cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); | ||
2126 | } | ||
2127 | |||
2128 | public virtual void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) | ||
2129 | { | ||
2130 | lock (m_dbLock) | ||
2131 | { | ||
2132 | RemoveItems(primID); | ||
2133 | |||
2134 | if (items.Count == 0) | ||
2135 | return; | ||
2136 | |||
2137 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2138 | { | ||
2139 | dbcon.Open(); | ||
2140 | |||
2141 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2142 | { | ||
2143 | cmd.CommandText = "insert into primitems (" + | ||
2144 | "invType, assetType, name, " + | ||
2145 | "description, creationDate, nextPermissions, " + | ||
2146 | "currentPermissions, basePermissions, " + | ||
2147 | "everyonePermissions, groupPermissions, " + | ||
2148 | "flags, itemID, primID, assetID, " + | ||
2149 | "parentFolderID, creatorID, ownerID, " + | ||
2150 | "groupID, lastOwnerID) values (?invType, " + | ||
2151 | "?assetType, ?name, ?description, " + | ||
2152 | "?creationDate, ?nextPermissions, " + | ||
2153 | "?currentPermissions, ?basePermissions, " + | ||
2154 | "?everyonePermissions, ?groupPermissions, " + | ||
2155 | "?flags, ?itemID, ?primID, ?assetID, " + | ||
2156 | "?parentFolderID, ?creatorID, ?ownerID, " + | ||
2157 | "?groupID, ?lastOwnerID)"; | ||
2158 | |||
2159 | foreach (TaskInventoryItem item in items) | ||
2160 | { | ||
2161 | cmd.Parameters.Clear(); | ||
2162 | |||
2163 | FillItemCommand(cmd, item); | ||
2164 | |||
2165 | ExecuteNonQuery(cmd); | ||
2166 | } | ||
2167 | } | ||
2168 | dbcon.Close(); | ||
2169 | } | ||
2170 | } | ||
2171 | } | ||
2172 | |||
2173 | public UUID[] GetObjectIDs(UUID regionID) | ||
2174 | { | ||
2175 | List<UUID> uuids = new List<UUID>(); | ||
2176 | |||
2177 | lock (m_dbLock) | ||
2178 | { | ||
2179 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2180 | { | ||
2181 | dbcon.Open(); | ||
2182 | |||
2183 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2184 | { | ||
2185 | cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID and SceneGroupID = UUID"; | ||
2186 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
2187 | |||
2188 | using (IDataReader reader = ExecuteReader(cmd)) | ||
2189 | { | ||
2190 | while (reader.Read()) | ||
2191 | { | ||
2192 | UUID id = new UUID(reader["UUID"].ToString()); | ||
2193 | |||
2194 | uuids.Add(id); | ||
2195 | } | ||
2196 | } | ||
2197 | } | ||
2198 | dbcon.Close(); | ||
2199 | } | ||
2200 | } | ||
2201 | |||
2202 | return uuids.ToArray(); | ||
2203 | } | ||
2204 | |||
2205 | private void LoadSpawnPoints(RegionSettings rs) | ||
2206 | { | ||
2207 | rs.ClearSpawnPoints(); | ||
2208 | |||
2209 | lock (m_dbLock) | ||
2210 | { | ||
2211 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2212 | { | ||
2213 | dbcon.Open(); | ||
2214 | |||
2215 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2216 | { | ||
2217 | cmd.CommandText = "select Yaw, Pitch, Distance from spawn_points where RegionID = ?RegionID"; | ||
2218 | cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString()); | ||
2219 | |||
2220 | using (IDataReader r = cmd.ExecuteReader()) | ||
2221 | { | ||
2222 | while (r.Read()) | ||
2223 | { | ||
2224 | SpawnPoint sp = new SpawnPoint(); | ||
2225 | |||
2226 | sp.Yaw = (float)r["Yaw"]; | ||
2227 | sp.Pitch = (float)r["Pitch"]; | ||
2228 | sp.Distance = (float)r["Distance"]; | ||
2229 | |||
2230 | rs.AddSpawnPoint(sp); | ||
2231 | } | ||
2232 | } | ||
2233 | } | ||
2234 | dbcon.Close(); | ||
2235 | } | ||
2236 | } | ||
2237 | } | ||
2238 | |||
2239 | private void SaveSpawnPoints(RegionSettings rs) | ||
2240 | { | ||
2241 | lock (m_dbLock) | ||
2242 | { | ||
2243 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2244 | { | ||
2245 | dbcon.Open(); | ||
2246 | |||
2247 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2248 | { | ||
2249 | cmd.CommandText = "delete from spawn_points where RegionID = ?RegionID"; | ||
2250 | cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString()); | ||
2251 | |||
2252 | cmd.ExecuteNonQuery(); | ||
2253 | |||
2254 | cmd.Parameters.Clear(); | ||
2255 | |||
2256 | cmd.CommandText = "insert into spawn_points (RegionID, Yaw, Pitch, Distance) values ( ?RegionID, ?Yaw, ?Pitch, ?Distance)"; | ||
2257 | |||
2258 | foreach (SpawnPoint p in rs.SpawnPoints()) | ||
2259 | { | ||
2260 | cmd.Parameters.AddWithValue("?RegionID", rs.RegionUUID.ToString()); | ||
2261 | cmd.Parameters.AddWithValue("?Yaw", p.Yaw); | ||
2262 | cmd.Parameters.AddWithValue("?Pitch", p.Pitch); | ||
2263 | cmd.Parameters.AddWithValue("?Distance", p.Distance); | ||
2264 | |||
2265 | cmd.ExecuteNonQuery(); | ||
2266 | cmd.Parameters.Clear(); | ||
2267 | } | ||
2268 | } | ||
2269 | dbcon.Close(); | ||
2270 | } | ||
2271 | } | ||
2272 | } | ||
2273 | |||
2274 | public void SaveExtra(UUID regionID, string name, string val) | ||
2275 | { | ||
2276 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2277 | { | ||
2278 | dbcon.Open(); | ||
2279 | |||
2280 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2281 | { | ||
2282 | cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)"; | ||
2283 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
2284 | cmd.Parameters.AddWithValue("?Name", name); | ||
2285 | cmd.Parameters.AddWithValue("?value", val); | ||
2286 | |||
2287 | cmd.ExecuteNonQuery(); | ||
2288 | } | ||
2289 | dbcon.Close(); | ||
2290 | } | ||
2291 | } | ||
2292 | |||
2293 | public void RemoveExtra(UUID regionID, string name) | ||
2294 | { | ||
2295 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2296 | { | ||
2297 | dbcon.Open(); | ||
2298 | |||
2299 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2300 | { | ||
2301 | cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name"; | ||
2302 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
2303 | cmd.Parameters.AddWithValue("?Name", name); | ||
2304 | |||
2305 | cmd.ExecuteNonQuery(); | ||
2306 | } | ||
2307 | dbcon.Close(); | ||
2308 | } | ||
2309 | } | ||
2310 | |||
2311 | public Dictionary<string, string> GetExtra(UUID regionID) | ||
2312 | { | ||
2313 | Dictionary<string, string> ret = new Dictionary<string, string>(); | ||
2314 | |||
2315 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
2316 | { | ||
2317 | dbcon.Open(); | ||
2318 | |||
2319 | using (MySqlCommand cmd = dbcon.CreateCommand()) | ||
2320 | { | ||
2321 | cmd.CommandText = "select * from regionextra where RegionID=?RegionID"; | ||
2322 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
2323 | using (IDataReader r = cmd.ExecuteReader()) | ||
2324 | { | ||
2325 | while (r.Read()) | ||
2326 | { | ||
2327 | ret[r["Name"].ToString()] = r["value"].ToString(); | ||
2328 | } | ||
2329 | } | ||
2330 | } | ||
2331 | dbcon.Close(); | ||
2332 | } | ||
2333 | |||
2334 | return ret; | ||
2335 | } | ||
2336 | } | ||
2337 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs new file mode 100644 index 0000000..59cfe70 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | bool valid = false; | ||
50 | |||
51 | for (int i = 0 ; i < words.Length ; i++) | ||
52 | { | ||
53 | if (words[i].Length > 2) | ||
54 | valid = true; | ||
55 | // if (words[i].Length < 3) | ||
56 | // { | ||
57 | // if (i != words.Length - 1) | ||
58 | // Array.Copy(words, i + 1, words, i, words.Length - i - 1); | ||
59 | // Array.Resize(ref words, words.Length - 1); | ||
60 | // } | ||
61 | } | ||
62 | |||
63 | if ((!valid) || words.Length == 0) | ||
64 | return new UserAccountData[0]; | ||
65 | |||
66 | if (words.Length > 2) | ||
67 | return new UserAccountData[0]; | ||
68 | |||
69 | using (MySqlCommand cmd = new MySqlCommand()) | ||
70 | { | ||
71 | if (words.Length == 1) | ||
72 | { | ||
73 | cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm); | ||
74 | cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%"); | ||
75 | cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm); | ||
80 | cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%"); | ||
81 | cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%"); | ||
82 | cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); | ||
83 | } | ||
84 | |||
85 | return DoQuery(cmd); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | public UserAccountData[] GetUsersWhere(UUID scopeID, string where) | ||
90 | { | ||
91 | using (MySqlCommand cmd = new MySqlCommand()) | ||
92 | { | ||
93 | if (scopeID != UUID.Zero) | ||
94 | { | ||
95 | where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")"; | ||
96 | cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); | ||
97 | } | ||
98 | |||
99 | cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm); | ||
100 | |||
101 | return DoQuery(cmd); | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs new file mode 100644 index 0000000..16637c3 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs | |||
@@ -0,0 +1,1030 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
73 | } | ||
74 | } | ||
75 | #endregion Member Functions | ||
76 | |||
77 | #region Classifieds Queries | ||
78 | /// <summary> | ||
79 | /// Gets the classified records. | ||
80 | /// </summary> | ||
81 | /// <returns> | ||
82 | /// Array of classified records | ||
83 | /// </returns> | ||
84 | /// <param name='creatorId'> | ||
85 | /// Creator identifier. | ||
86 | /// </param> | ||
87 | public OSDArray GetClassifiedRecords(UUID creatorId) | ||
88 | { | ||
89 | OSDArray data = new OSDArray(); | ||
90 | |||
91 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
92 | { | ||
93 | const string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; | ||
94 | dbcon.Open(); | ||
95 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
96 | { | ||
97 | cmd.Parameters.AddWithValue("?Id", creatorId); | ||
98 | using( MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) | ||
99 | { | ||
100 | if(reader.HasRows) | ||
101 | { | ||
102 | while (reader.Read()) | ||
103 | { | ||
104 | OSDMap n = new OSDMap(); | ||
105 | UUID Id = UUID.Zero; | ||
106 | |||
107 | string Name = null; | ||
108 | try | ||
109 | { | ||
110 | UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id); | ||
111 | Name = Convert.ToString(reader["name"]); | ||
112 | } | ||
113 | catch (Exception e) | ||
114 | { | ||
115 | m_log.ErrorFormat("[PROFILES_DATA] GetClassifiedRecords exception {0}", e.Message); | ||
116 | } | ||
117 | n.Add("classifieduuid", OSD.FromUUID(Id)); | ||
118 | n.Add("name", OSD.FromString(Name)); | ||
119 | data.Add(n); | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | } | ||
124 | dbcon.Close(); | ||
125 | } | ||
126 | return data; | ||
127 | } | ||
128 | |||
129 | public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) | ||
130 | { | ||
131 | const string query = | ||
132 | "INSERT INTO classifieds (" | ||
133 | + "`classifieduuid`," | ||
134 | + "`creatoruuid`," | ||
135 | + "`creationdate`," | ||
136 | + "`expirationdate`," | ||
137 | + "`category`," | ||
138 | + "`name`," | ||
139 | + "`description`," | ||
140 | + "`parceluuid`," | ||
141 | + "`parentestate`," | ||
142 | + "`snapshotuuid`," | ||
143 | + "`simname`," | ||
144 | + "`posglobal`," | ||
145 | + "`parcelname`," | ||
146 | + "`classifiedflags`," | ||
147 | + "`priceforlisting`) " | ||
148 | + "VALUES (" | ||
149 | + "?ClassifiedId," | ||
150 | + "?CreatorId," | ||
151 | + "?CreatedDate," | ||
152 | + "?ExpirationDate," | ||
153 | + "?Category," | ||
154 | + "?Name," | ||
155 | + "?Description," | ||
156 | + "?ParcelId," | ||
157 | + "?ParentEstate," | ||
158 | + "?SnapshotId," | ||
159 | + "?SimName," | ||
160 | + "?GlobalPos," | ||
161 | + "?ParcelName," | ||
162 | + "?Flags," | ||
163 | + "?ListingPrice ) " | ||
164 | + "ON DUPLICATE KEY UPDATE " | ||
165 | + "category=?Category, " | ||
166 | + "expirationdate=?ExpirationDate, " | ||
167 | + "name=?Name, " | ||
168 | + "description=?Description, " | ||
169 | + "parentestate=?ParentEstate, " | ||
170 | + "posglobal=?GlobalPos, " | ||
171 | + "parcelname=?ParcelName, " | ||
172 | + "classifiedflags=?Flags, " | ||
173 | + "priceforlisting=?ListingPrice, " | ||
174 | + "snapshotuuid=?SnapshotId" | ||
175 | ; | ||
176 | |||
177 | if(string.IsNullOrEmpty(ad.ParcelName)) | ||
178 | ad.ParcelName = "Unknown"; | ||
179 | if(ad.ParcelId == null) | ||
180 | ad.ParcelId = UUID.Zero; | ||
181 | if(string.IsNullOrEmpty(ad.Description)) | ||
182 | ad.Description = "No Description"; | ||
183 | |||
184 | DateTime epoch = new DateTime(1970, 1, 1); | ||
185 | DateTime now = DateTime.Now; | ||
186 | TimeSpan epochnow = now - epoch; | ||
187 | TimeSpan duration; | ||
188 | DateTime expiration; | ||
189 | TimeSpan epochexp; | ||
190 | |||
191 | if(ad.Flags == 2) | ||
192 | { | ||
193 | duration = new TimeSpan(7,0,0,0); | ||
194 | expiration = now.Add(duration); | ||
195 | epochexp = expiration - epoch; | ||
196 | } | ||
197 | else | ||
198 | { | ||
199 | duration = new TimeSpan(365,0,0,0); | ||
200 | expiration = now.Add(duration); | ||
201 | epochexp = expiration - epoch; | ||
202 | } | ||
203 | ad.CreationDate = (int)epochnow.TotalSeconds; | ||
204 | ad.ExpirationDate = (int)epochexp.TotalSeconds; | ||
205 | |||
206 | try | ||
207 | { | ||
208 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
209 | { | ||
210 | dbcon.Open(); | ||
211 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
212 | { | ||
213 | cmd.Parameters.AddWithValue("?ClassifiedId", ad.ClassifiedId.ToString()); | ||
214 | cmd.Parameters.AddWithValue("?CreatorId", ad.CreatorId.ToString()); | ||
215 | cmd.Parameters.AddWithValue("?CreatedDate", ad.CreationDate.ToString()); | ||
216 | cmd.Parameters.AddWithValue("?ExpirationDate", ad.ExpirationDate.ToString()); | ||
217 | cmd.Parameters.AddWithValue("?Category", ad.Category.ToString()); | ||
218 | cmd.Parameters.AddWithValue("?Name", ad.Name.ToString()); | ||
219 | cmd.Parameters.AddWithValue("?Description", ad.Description.ToString()); | ||
220 | cmd.Parameters.AddWithValue("?ParcelId", ad.ParcelId.ToString()); | ||
221 | cmd.Parameters.AddWithValue("?ParentEstate", ad.ParentEstate.ToString()); | ||
222 | cmd.Parameters.AddWithValue("?SnapshotId", ad.SnapshotId.ToString ()); | ||
223 | cmd.Parameters.AddWithValue("?SimName", ad.SimName.ToString()); | ||
224 | cmd.Parameters.AddWithValue("?GlobalPos", ad.GlobalPos.ToString()); | ||
225 | cmd.Parameters.AddWithValue("?ParcelName", ad.ParcelName.ToString()); | ||
226 | cmd.Parameters.AddWithValue("?Flags", ad.Flags.ToString()); | ||
227 | cmd.Parameters.AddWithValue("?ListingPrice", ad.Price.ToString ()); | ||
228 | |||
229 | cmd.ExecuteNonQuery(); | ||
230 | } | ||
231 | dbcon.Close(); | ||
232 | } | ||
233 | } | ||
234 | catch (Exception e) | ||
235 | { | ||
236 | m_log.ErrorFormat("[PROFILES_DATA]: UpdateClassifiedRecord exception {0}", e.Message); | ||
237 | result = e.Message; | ||
238 | return false; | ||
239 | } | ||
240 | return true; | ||
241 | } | ||
242 | |||
243 | public bool DeleteClassifiedRecord(UUID recordId) | ||
244 | { | ||
245 | const string query = "DELETE FROM classifieds WHERE classifieduuid = ?recordId"; | ||
246 | |||
247 | try | ||
248 | { | ||
249 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
250 | { | ||
251 | dbcon.Open(); | ||
252 | |||
253 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
254 | { | ||
255 | cmd.Parameters.AddWithValue("?recordId", recordId.ToString()); | ||
256 | cmd.ExecuteNonQuery(); | ||
257 | } | ||
258 | dbcon.Close(); | ||
259 | } | ||
260 | } | ||
261 | catch (Exception e) | ||
262 | { | ||
263 | m_log.ErrorFormat("[PROFILES_DATA]: DeleteClassifiedRecord exception {0}", e.Message); | ||
264 | return false; | ||
265 | } | ||
266 | return true; | ||
267 | } | ||
268 | |||
269 | public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) | ||
270 | { | ||
271 | |||
272 | const string query = "SELECT * FROM classifieds WHERE classifieduuid = ?AdId"; | ||
273 | |||
274 | try | ||
275 | { | ||
276 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
277 | { | ||
278 | dbcon.Open(); | ||
279 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
280 | { | ||
281 | cmd.Parameters.AddWithValue("?AdId", ad.ClassifiedId.ToString()); | ||
282 | |||
283 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
284 | { | ||
285 | if(reader.Read ()) | ||
286 | { | ||
287 | ad.CreatorId = new UUID(reader.GetGuid("creatoruuid")); | ||
288 | ad.ParcelId = new UUID(reader.GetGuid("parceluuid")); | ||
289 | ad.SnapshotId = new UUID(reader.GetGuid("snapshotuuid")); | ||
290 | ad.CreationDate = Convert.ToInt32(reader["creationdate"]); | ||
291 | ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]); | ||
292 | ad.ParentEstate = Convert.ToInt32(reader["parentestate"]); | ||
293 | ad.Flags = (byte)reader.GetUInt32("classifiedflags"); | ||
294 | ad.Category = reader.GetInt32("category"); | ||
295 | ad.Price = reader.GetInt16("priceforlisting"); | ||
296 | ad.Name = reader.GetString("name"); | ||
297 | ad.Description = reader.GetString("description"); | ||
298 | ad.SimName = reader.GetString("simname"); | ||
299 | ad.GlobalPos = reader.GetString("posglobal"); | ||
300 | ad.ParcelName = reader.GetString("parcelname"); | ||
301 | |||
302 | } | ||
303 | } | ||
304 | } | ||
305 | dbcon.Close(); | ||
306 | } | ||
307 | } | ||
308 | catch (Exception e) | ||
309 | { | ||
310 | m_log.ErrorFormat("[PROFILES_DATA]: GetClassifiedInfo exception {0}", e.Message); | ||
311 | } | ||
312 | return true; | ||
313 | } | ||
314 | #endregion Classifieds Queries | ||
315 | |||
316 | #region Picks Queries | ||
317 | public OSDArray GetAvatarPicks(UUID avatarId) | ||
318 | { | ||
319 | const string query = "SELECT `pickuuid`,`name` FROM userpicks WHERE creatoruuid = ?Id"; | ||
320 | |||
321 | OSDArray data = new OSDArray(); | ||
322 | |||
323 | try | ||
324 | { | ||
325 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
326 | { | ||
327 | dbcon.Open(); | ||
328 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
329 | { | ||
330 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
331 | |||
332 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
333 | { | ||
334 | if(reader.HasRows) | ||
335 | { | ||
336 | while (reader.Read()) | ||
337 | { | ||
338 | OSDMap record = new OSDMap(); | ||
339 | |||
340 | record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"])); | ||
341 | record.Add("name",OSD.FromString((string)reader["name"])); | ||
342 | data.Add(record); | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | dbcon.Close(); | ||
348 | } | ||
349 | } | ||
350 | catch (Exception e) | ||
351 | { | ||
352 | m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarPicks exception {0}", e.Message); | ||
353 | } | ||
354 | return data; | ||
355 | } | ||
356 | |||
357 | public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) | ||
358 | { | ||
359 | UserProfilePick pick = new UserProfilePick(); | ||
360 | const string query = "SELECT * FROM userpicks WHERE creatoruuid = ?CreatorId AND pickuuid = ?PickId"; | ||
361 | |||
362 | try | ||
363 | { | ||
364 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
365 | { | ||
366 | dbcon.Open(); | ||
367 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
368 | { | ||
369 | cmd.Parameters.AddWithValue("?CreatorId", avatarId.ToString()); | ||
370 | cmd.Parameters.AddWithValue("?PickId", pickId.ToString()); | ||
371 | |||
372 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
373 | { | ||
374 | if(reader.HasRows) | ||
375 | { | ||
376 | reader.Read(); | ||
377 | |||
378 | string description = (string)reader["description"]; | ||
379 | |||
380 | if (string.IsNullOrEmpty(description)) | ||
381 | description = "No description given."; | ||
382 | |||
383 | UUID.TryParse((string)reader["pickuuid"], out pick.PickId); | ||
384 | UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId); | ||
385 | UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId); | ||
386 | UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId); | ||
387 | pick.GlobalPos = (string)reader["posglobal"]; | ||
388 | pick.Gatekeeper = (string)reader["gatekeeper"]; | ||
389 | bool.TryParse((string)reader["toppick"], out pick.TopPick); | ||
390 | bool.TryParse((string)reader["enabled"], out pick.Enabled); | ||
391 | pick.Name = (string)reader["name"]; | ||
392 | pick.Desc = description; | ||
393 | pick.ParcelName = (string)reader["user"]; | ||
394 | pick.OriginalName = (string)reader["originalname"]; | ||
395 | pick.SimName = (string)reader["simname"]; | ||
396 | pick.SortOrder = (int)reader["sortorder"]; | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | dbcon.Close(); | ||
401 | } | ||
402 | } | ||
403 | catch (Exception e) | ||
404 | { | ||
405 | m_log.ErrorFormat("[PROFILES_DATA]: GetPickInfo exception {0}", e.Message); | ||
406 | } | ||
407 | return pick; | ||
408 | } | ||
409 | |||
410 | public bool UpdatePicksRecord(UserProfilePick pick) | ||
411 | { | ||
412 | const string query = | ||
413 | "INSERT INTO userpicks VALUES (" | ||
414 | + "?PickId," | ||
415 | + "?CreatorId," | ||
416 | + "?TopPick," | ||
417 | + "?ParcelId," | ||
418 | + "?Name," | ||
419 | + "?Desc," | ||
420 | + "?SnapshotId," | ||
421 | + "?User," | ||
422 | + "?Original," | ||
423 | + "?SimName," | ||
424 | + "?GlobalPos," | ||
425 | + "?SortOrder," | ||
426 | + "?Enabled," | ||
427 | + "?Gatekeeper)" | ||
428 | + "ON DUPLICATE KEY UPDATE " | ||
429 | + "parceluuid=?ParcelId," | ||
430 | + "name=?Name," | ||
431 | + "description=?Desc," | ||
432 | + "user=?User," | ||
433 | + "simname=?SimName," | ||
434 | + "snapshotuuid=?SnapshotId," | ||
435 | + "pickuuid=?PickId," | ||
436 | + "posglobal=?GlobalPos," | ||
437 | + "gatekeeper=?Gatekeeper" | ||
438 | ; | ||
439 | |||
440 | try | ||
441 | { | ||
442 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
443 | { | ||
444 | dbcon.Open(); | ||
445 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
446 | { | ||
447 | cmd.Parameters.AddWithValue("?PickId", pick.PickId.ToString()); | ||
448 | cmd.Parameters.AddWithValue("?CreatorId", pick.CreatorId.ToString()); | ||
449 | cmd.Parameters.AddWithValue("?TopPick", pick.TopPick.ToString()); | ||
450 | cmd.Parameters.AddWithValue("?ParcelId", pick.ParcelId.ToString()); | ||
451 | cmd.Parameters.AddWithValue("?Name", pick.Name.ToString()); | ||
452 | cmd.Parameters.AddWithValue("?Desc", pick.Desc.ToString()); | ||
453 | cmd.Parameters.AddWithValue("?SnapshotId", pick.SnapshotId.ToString()); | ||
454 | cmd.Parameters.AddWithValue("?User", pick.ParcelName.ToString()); | ||
455 | cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString()); | ||
456 | cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString()); | ||
457 | cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos); | ||
458 | cmd.Parameters.AddWithValue("?Gatekeeper",pick.Gatekeeper); | ||
459 | cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ()); | ||
460 | cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString()); | ||
461 | |||
462 | cmd.ExecuteNonQuery(); | ||
463 | } | ||
464 | dbcon.Close(); | ||
465 | } | ||
466 | } | ||
467 | catch (Exception e) | ||
468 | { | ||
469 | m_log.ErrorFormat("[PROFILES_DATA]: UpdatePicksRecord exception {0}", e.Message); | ||
470 | return false; | ||
471 | } | ||
472 | return true; | ||
473 | } | ||
474 | |||
475 | public bool DeletePicksRecord(UUID pickId) | ||
476 | { | ||
477 | string query = "DELETE FROM userpicks WHERE pickuuid = ?PickId"; | ||
478 | |||
479 | try | ||
480 | { | ||
481 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
482 | { | ||
483 | dbcon.Open(); | ||
484 | |||
485 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
486 | { | ||
487 | cmd.Parameters.AddWithValue("?PickId", pickId.ToString()); | ||
488 | |||
489 | cmd.ExecuteNonQuery(); | ||
490 | } | ||
491 | dbcon.Close(); | ||
492 | } | ||
493 | } | ||
494 | catch (Exception e) | ||
495 | { | ||
496 | m_log.ErrorFormat("[PROFILES_DATA]: DeletePicksRecord exception {0}", e.Message); | ||
497 | return false; | ||
498 | } | ||
499 | return true; | ||
500 | } | ||
501 | #endregion Picks Queries | ||
502 | |||
503 | #region Avatar Notes Queries | ||
504 | public bool GetAvatarNotes(ref UserProfileNotes notes) | ||
505 | { // WIP | ||
506 | const string query = "SELECT `notes` FROM usernotes WHERE useruuid = ?Id AND targetuuid = ?TargetId"; | ||
507 | |||
508 | try | ||
509 | { | ||
510 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
511 | { | ||
512 | dbcon.Open(); | ||
513 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
514 | { | ||
515 | cmd.Parameters.AddWithValue("?Id", notes.UserId.ToString()); | ||
516 | cmd.Parameters.AddWithValue("?TargetId", notes.TargetId.ToString()); | ||
517 | |||
518 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
519 | { | ||
520 | if(reader.HasRows) | ||
521 | { | ||
522 | reader.Read(); | ||
523 | notes.Notes = OSD.FromString((string)reader["notes"]); | ||
524 | } | ||
525 | else | ||
526 | { | ||
527 | notes.Notes = OSD.FromString(""); | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | dbcon.Close(); | ||
532 | } | ||
533 | } | ||
534 | catch (Exception e) | ||
535 | { | ||
536 | m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarNotes exception {0}", e.Message); | ||
537 | } | ||
538 | return true; | ||
539 | } | ||
540 | |||
541 | public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) | ||
542 | { | ||
543 | string query; | ||
544 | bool remove; | ||
545 | |||
546 | if(string.IsNullOrEmpty(note.Notes)) | ||
547 | { | ||
548 | remove = true; | ||
549 | query = "DELETE FROM usernotes WHERE useruuid=?UserId AND targetuuid=?TargetId"; | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | remove = false; | ||
554 | query = "INSERT INTO usernotes VALUES (" | ||
555 | + "?UserId," | ||
556 | + "?TargetId," | ||
557 | + "?Notes )" | ||
558 | + "ON DUPLICATE KEY " | ||
559 | + "UPDATE " | ||
560 | + "notes=?Notes" | ||
561 | ; | ||
562 | } | ||
563 | |||
564 | try | ||
565 | { | ||
566 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
567 | { | ||
568 | dbcon.Open(); | ||
569 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
570 | { | ||
571 | if(!remove) | ||
572 | cmd.Parameters.AddWithValue("?Notes", note.Notes); | ||
573 | cmd.Parameters.AddWithValue("?TargetId", note.TargetId.ToString ()); | ||
574 | cmd.Parameters.AddWithValue("?UserId", note.UserId.ToString()); | ||
575 | |||
576 | cmd.ExecuteNonQuery(); | ||
577 | } | ||
578 | dbcon.Close(); | ||
579 | } | ||
580 | } | ||
581 | catch (Exception e) | ||
582 | { | ||
583 | m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarNotes exception {0}", e.Message); | ||
584 | return false; | ||
585 | } | ||
586 | return true; | ||
587 | |||
588 | } | ||
589 | #endregion Avatar Notes Queries | ||
590 | |||
591 | #region Avatar Properties | ||
592 | public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) | ||
593 | { | ||
594 | string query = "SELECT * FROM userprofile WHERE useruuid = ?Id"; | ||
595 | |||
596 | try | ||
597 | { | ||
598 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
599 | { | ||
600 | dbcon.Open(); | ||
601 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
602 | { | ||
603 | cmd.Parameters.AddWithValue("?Id", props.UserId.ToString()); | ||
604 | |||
605 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
606 | { | ||
607 | if(reader.HasRows) | ||
608 | { | ||
609 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
610 | ": Getting data for {0}.", props.UserId); | ||
611 | reader.Read(); | ||
612 | props.WebUrl = (string)reader["profileURL"]; | ||
613 | UUID.TryParse((string)reader["profileImage"], out props.ImageId); | ||
614 | props.AboutText = (string)reader["profileAboutText"]; | ||
615 | UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId); | ||
616 | props.FirstLifeText = (string)reader["profileFirstText"]; | ||
617 | UUID.TryParse((string)reader["profilePartner"], out props.PartnerId); | ||
618 | props.WantToMask = (int)reader["profileWantToMask"]; | ||
619 | props.WantToText = (string)reader["profileWantToText"]; | ||
620 | props.SkillsMask = (int)reader["profileSkillsMask"]; | ||
621 | props.SkillsText = (string)reader["profileSkillsText"]; | ||
622 | props.Language = (string)reader["profileLanguages"]; | ||
623 | } | ||
624 | else | ||
625 | { | ||
626 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
627 | ": No data for {0}", props.UserId); | ||
628 | |||
629 | props.WebUrl = string.Empty; | ||
630 | props.ImageId = UUID.Zero; | ||
631 | props.AboutText = string.Empty; | ||
632 | props.FirstLifeImageId = UUID.Zero; | ||
633 | props.FirstLifeText = string.Empty; | ||
634 | props.PartnerId = UUID.Zero; | ||
635 | props.WantToMask = 0; | ||
636 | props.WantToText = string.Empty; | ||
637 | props.SkillsMask = 0; | ||
638 | props.SkillsText = string.Empty; | ||
639 | props.Language = string.Empty; | ||
640 | props.PublishProfile = false; | ||
641 | props.PublishMature = false; | ||
642 | |||
643 | query = "INSERT INTO userprofile (" | ||
644 | + "useruuid, " | ||
645 | + "profilePartner, " | ||
646 | + "profileAllowPublish, " | ||
647 | + "profileMaturePublish, " | ||
648 | + "profileURL, " | ||
649 | + "profileWantToMask, " | ||
650 | + "profileWantToText, " | ||
651 | + "profileSkillsMask, " | ||
652 | + "profileSkillsText, " | ||
653 | + "profileLanguages, " | ||
654 | + "profileImage, " | ||
655 | + "profileAboutText, " | ||
656 | + "profileFirstImage, " | ||
657 | + "profileFirstText) VALUES (" | ||
658 | + "?userId, " | ||
659 | + "?profilePartner, " | ||
660 | + "?profileAllowPublish, " | ||
661 | + "?profileMaturePublish, " | ||
662 | + "?profileURL, " | ||
663 | + "?profileWantToMask, " | ||
664 | + "?profileWantToText, " | ||
665 | + "?profileSkillsMask, " | ||
666 | + "?profileSkillsText, " | ||
667 | + "?profileLanguages, " | ||
668 | + "?profileImage, " | ||
669 | + "?profileAboutText, " | ||
670 | + "?profileFirstImage, " | ||
671 | + "?profileFirstText)" | ||
672 | ; | ||
673 | |||
674 | dbcon.Close(); | ||
675 | dbcon.Open(); | ||
676 | |||
677 | using (MySqlCommand put = new MySqlCommand(query, dbcon)) | ||
678 | { | ||
679 | put.Parameters.AddWithValue("?userId", props.UserId.ToString()); | ||
680 | put.Parameters.AddWithValue("?profilePartner", props.PartnerId.ToString()); | ||
681 | put.Parameters.AddWithValue("?profileAllowPublish", props.PublishProfile); | ||
682 | put.Parameters.AddWithValue("?profileMaturePublish", props.PublishMature); | ||
683 | put.Parameters.AddWithValue("?profileURL", props.WebUrl); | ||
684 | put.Parameters.AddWithValue("?profileWantToMask", props.WantToMask); | ||
685 | put.Parameters.AddWithValue("?profileWantToText", props.WantToText); | ||
686 | put.Parameters.AddWithValue("?profileSkillsMask", props.SkillsMask); | ||
687 | put.Parameters.AddWithValue("?profileSkillsText", props.SkillsText); | ||
688 | put.Parameters.AddWithValue("?profileLanguages", props.Language); | ||
689 | put.Parameters.AddWithValue("?profileImage", props.ImageId.ToString()); | ||
690 | put.Parameters.AddWithValue("?profileAboutText", props.AboutText); | ||
691 | put.Parameters.AddWithValue("?profileFirstImage", props.FirstLifeImageId.ToString()); | ||
692 | put.Parameters.AddWithValue("?profileFirstText", props.FirstLifeText); | ||
693 | |||
694 | put.ExecuteNonQuery(); | ||
695 | } | ||
696 | } | ||
697 | } | ||
698 | } | ||
699 | dbcon.Close(); | ||
700 | } | ||
701 | } | ||
702 | catch (Exception e) | ||
703 | { | ||
704 | m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarProperties exception {0}", e.Message); | ||
705 | result = e.Message; | ||
706 | return false; | ||
707 | } | ||
708 | return true; | ||
709 | } | ||
710 | |||
711 | public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) | ||
712 | { | ||
713 | const string query = "UPDATE userprofile SET profileURL=?profileURL," | ||
714 | + "profileImage=?image, profileAboutText=?abouttext," | ||
715 | + "profileFirstImage=?firstlifeimage, profileFirstText=?firstlifetext " | ||
716 | + "WHERE useruuid=?uuid"; | ||
717 | |||
718 | try | ||
719 | { | ||
720 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
721 | { | ||
722 | dbcon.Open(); | ||
723 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
724 | { | ||
725 | cmd.Parameters.AddWithValue("?profileURL", props.WebUrl); | ||
726 | cmd.Parameters.AddWithValue("?image", props.ImageId.ToString()); | ||
727 | cmd.Parameters.AddWithValue("?abouttext", props.AboutText); | ||
728 | cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString()); | ||
729 | cmd.Parameters.AddWithValue("?firstlifetext", props.FirstLifeText); | ||
730 | cmd.Parameters.AddWithValue("?uuid", props.UserId.ToString()); | ||
731 | |||
732 | cmd.ExecuteNonQuery(); | ||
733 | } | ||
734 | dbcon.Close(); | ||
735 | } | ||
736 | } | ||
737 | catch (Exception e) | ||
738 | { | ||
739 | m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarProperties exception {0}", e.Message); | ||
740 | |||
741 | return false; | ||
742 | } | ||
743 | return true; | ||
744 | } | ||
745 | #endregion Avatar Properties | ||
746 | |||
747 | #region Avatar Interests | ||
748 | public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) | ||
749 | { | ||
750 | const string query = "UPDATE userprofile SET " | ||
751 | + "profileWantToMask=?WantMask, " | ||
752 | + "profileWantToText=?WantText," | ||
753 | + "profileSkillsMask=?SkillsMask," | ||
754 | + "profileSkillsText=?SkillsText, " | ||
755 | + "profileLanguages=?Languages " | ||
756 | + "WHERE useruuid=?uuid"; | ||
757 | |||
758 | try | ||
759 | { | ||
760 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
761 | { | ||
762 | dbcon.Open(); | ||
763 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
764 | { | ||
765 | cmd.Parameters.AddWithValue("?WantMask", up.WantToMask); | ||
766 | cmd.Parameters.AddWithValue("?WantText", up.WantToText); | ||
767 | cmd.Parameters.AddWithValue("?SkillsMask", up.SkillsMask); | ||
768 | cmd.Parameters.AddWithValue("?SkillsText", up.SkillsText); | ||
769 | cmd.Parameters.AddWithValue("?Languages", up.Language); | ||
770 | cmd.Parameters.AddWithValue("?uuid", up.UserId.ToString()); | ||
771 | |||
772 | cmd.ExecuteNonQuery(); | ||
773 | } | ||
774 | } | ||
775 | } | ||
776 | catch (Exception e) | ||
777 | { | ||
778 | m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarInterests exception {0}", e.Message); | ||
779 | result = e.Message; | ||
780 | return false; | ||
781 | } | ||
782 | return true; | ||
783 | } | ||
784 | #endregion Avatar Interests | ||
785 | |||
786 | public OSDArray GetUserImageAssets(UUID avatarId) | ||
787 | { | ||
788 | OSDArray data = new OSDArray(); | ||
789 | const string queryA = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; | ||
790 | |||
791 | // Get classified image assets | ||
792 | |||
793 | try | ||
794 | { | ||
795 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
796 | { | ||
797 | dbcon.Open(); | ||
798 | |||
799 | using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`classifieds`"), dbcon)) | ||
800 | { | ||
801 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
802 | |||
803 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
804 | { | ||
805 | if(reader.HasRows) | ||
806 | { | ||
807 | while (reader.Read()) | ||
808 | { | ||
809 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString ())); | ||
810 | } | ||
811 | } | ||
812 | } | ||
813 | } | ||
814 | |||
815 | dbcon.Close(); | ||
816 | dbcon.Open(); | ||
817 | |||
818 | using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`userpicks`"), dbcon)) | ||
819 | { | ||
820 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
821 | |||
822 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
823 | { | ||
824 | if(reader.HasRows) | ||
825 | { | ||
826 | while (reader.Read()) | ||
827 | { | ||
828 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString ())); | ||
829 | } | ||
830 | } | ||
831 | } | ||
832 | } | ||
833 | |||
834 | dbcon.Close(); | ||
835 | dbcon.Open(); | ||
836 | |||
837 | const string queryB = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; | ||
838 | |||
839 | using (MySqlCommand cmd = new MySqlCommand(string.Format (queryB,"`userpicks`"), dbcon)) | ||
840 | { | ||
841 | cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); | ||
842 | |||
843 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
844 | { | ||
845 | if(reader.HasRows) | ||
846 | { | ||
847 | while (reader.Read()) | ||
848 | { | ||
849 | data.Add(new OSDString((string)reader["profileImage"].ToString ())); | ||
850 | data.Add(new OSDString((string)reader["profileFirstImage"].ToString ())); | ||
851 | } | ||
852 | } | ||
853 | } | ||
854 | } | ||
855 | dbcon.Close(); | ||
856 | } | ||
857 | } | ||
858 | catch (Exception e) | ||
859 | { | ||
860 | m_log.ErrorFormat("[PROFILES_DATA]: GetUserImageAssets exception {0}", e.Message); | ||
861 | } | ||
862 | return data; | ||
863 | } | ||
864 | |||
865 | #region User Preferences | ||
866 | public bool GetUserPreferences(ref UserPreferences pref, ref string result) | ||
867 | { | ||
868 | const string query = "SELECT imviaemail,visible,email FROM usersettings WHERE useruuid = ?Id"; | ||
869 | |||
870 | try | ||
871 | { | ||
872 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
873 | { | ||
874 | dbcon.Open(); | ||
875 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
876 | { | ||
877 | cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString()); | ||
878 | using (MySqlDataReader reader = cmd.ExecuteReader()) | ||
879 | { | ||
880 | if (reader.HasRows) | ||
881 | { | ||
882 | reader.Read(); | ||
883 | bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail); | ||
884 | bool.TryParse((string)reader["visible"], out pref.Visible); | ||
885 | pref.EMail = (string)reader["email"]; | ||
886 | } | ||
887 | else | ||
888 | { | ||
889 | dbcon.Close(); | ||
890 | dbcon.Open(); | ||
891 | |||
892 | const string queryB = "INSERT INTO usersettings VALUES (?uuid,'false','false', ?Email)"; | ||
893 | |||
894 | using (MySqlCommand put = new MySqlCommand(queryB, dbcon)) | ||
895 | { | ||
896 | |||
897 | put.Parameters.AddWithValue("?Email", pref.EMail); | ||
898 | put.Parameters.AddWithValue("?uuid", pref.UserId.ToString()); | ||
899 | |||
900 | put.ExecuteNonQuery(); | ||
901 | } | ||
902 | } | ||
903 | } | ||
904 | } | ||
905 | dbcon.Close(); | ||
906 | } | ||
907 | } | ||
908 | catch (Exception e) | ||
909 | { | ||
910 | m_log.ErrorFormat("[PROFILES_DATA]: GetUserPreferences exception {0}", e.Message); | ||
911 | result = e.Message; | ||
912 | return false; | ||
913 | } | ||
914 | return true; | ||
915 | } | ||
916 | |||
917 | public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) | ||
918 | { | ||
919 | const string query = "UPDATE usersettings SET imviaemail=?ImViaEmail," | ||
920 | + "visible=?Visible, email=?EMail " | ||
921 | + "WHERE useruuid=?uuid"; | ||
922 | |||
923 | try | ||
924 | { | ||
925 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
926 | { | ||
927 | dbcon.Open(); | ||
928 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
929 | { | ||
930 | cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower()); | ||
931 | cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower()); | ||
932 | cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString()); | ||
933 | cmd.Parameters.AddWithValue("?EMail", pref.EMail.ToString().ToLower()); | ||
934 | |||
935 | cmd.ExecuteNonQuery(); | ||
936 | } | ||
937 | dbcon.Close(); | ||
938 | } | ||
939 | } | ||
940 | catch (Exception e) | ||
941 | { | ||
942 | m_log.ErrorFormat("[PROFILES_DATA]: UpdateUserPreferences exception {0} {1}", e.Message, e.InnerException); | ||
943 | result = e.Message; | ||
944 | return false; | ||
945 | } | ||
946 | return true; | ||
947 | } | ||
948 | #endregion User Preferences | ||
949 | |||
950 | #region Integration | ||
951 | public bool GetUserAppData(ref UserAppData props, ref string result) | ||
952 | { | ||
953 | const string query = "SELECT * FROM `userdata` WHERE UserId = ?Id AND TagId = ?TagId"; | ||
954 | |||
955 | try | ||
956 | { | ||
957 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
958 | { | ||
959 | dbcon.Open(); | ||
960 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
961 | { | ||
962 | cmd.Parameters.AddWithValue("?Id", props.UserId.ToString()); | ||
963 | cmd.Parameters.AddWithValue ("?TagId", props.TagId.ToString()); | ||
964 | |||
965 | using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
966 | { | ||
967 | if(reader.HasRows) | ||
968 | { | ||
969 | reader.Read(); | ||
970 | props.DataKey = (string)reader["DataKey"]; | ||
971 | props.DataVal = (string)reader["DataVal"]; | ||
972 | } | ||
973 | else | ||
974 | { | ||
975 | const string queryB = "INSERT INTO userdata VALUES (?UserId, ?TagId, ?DataKey, ?DataVal)"; | ||
976 | using (MySqlCommand put = new MySqlCommand(queryB, dbcon)) | ||
977 | { | ||
978 | put.Parameters.AddWithValue("?UserId", props.UserId.ToString()); | ||
979 | put.Parameters.AddWithValue("?TagId", props.TagId.ToString()); | ||
980 | put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString()); | ||
981 | put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString()); | ||
982 | |||
983 | put.ExecuteNonQuery(); | ||
984 | } | ||
985 | } | ||
986 | } | ||
987 | } | ||
988 | dbcon.Close(); | ||
989 | } | ||
990 | } | ||
991 | catch (Exception e) | ||
992 | { | ||
993 | m_log.ErrorFormat("[PROFILES_DATA]: GetUserAppData exception {0}", e.Message); | ||
994 | result = e.Message; | ||
995 | return false; | ||
996 | } | ||
997 | return true; | ||
998 | } | ||
999 | |||
1000 | public bool SetUserAppData(UserAppData props, ref string result) | ||
1001 | { | ||
1002 | const string query = "UPDATE userdata SET TagId = ?TagId, DataKey = ?DataKey, DataVal = ?DataVal WHERE UserId = ?UserId AND TagId = ?TagId"; | ||
1003 | |||
1004 | try | ||
1005 | { | ||
1006 | using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) | ||
1007 | { | ||
1008 | dbcon.Open(); | ||
1009 | using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) | ||
1010 | { | ||
1011 | cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString()); | ||
1012 | cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString()); | ||
1013 | cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString()); | ||
1014 | cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString()); | ||
1015 | |||
1016 | cmd.ExecuteNonQuery(); | ||
1017 | } | ||
1018 | dbcon.Close(); | ||
1019 | } | ||
1020 | } | ||
1021 | catch (Exception e) | ||
1022 | { | ||
1023 | m_log.ErrorFormat("[PROFILES_DATA]: SetUserAppData exception {0}", e.Message); | ||
1024 | return false; | ||
1025 | } | ||
1026 | return true; | ||
1027 | } | ||
1028 | #endregion Integration | ||
1029 | } | ||
1030 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs new file mode 100644 index 0000000..9f9c9cf --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs | |||
@@ -0,0 +1,522 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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 | dbcon.Close(); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | public void Initialise() | ||
105 | { | ||
106 | throw new NotImplementedException(); | ||
107 | } | ||
108 | |||
109 | public void Dispose() { } | ||
110 | |||
111 | /// <summary> | ||
112 | /// The name of this DB provider | ||
113 | /// </summary> | ||
114 | public string Name | ||
115 | { | ||
116 | get { return "MySQL XAsset storage engine"; } | ||
117 | } | ||
118 | |||
119 | #endregion | ||
120 | |||
121 | #region IAssetDataPlugin Members | ||
122 | |||
123 | /// <summary> | ||
124 | /// Fetch Asset <paramref name="assetID"/> from database | ||
125 | /// </summary> | ||
126 | /// <param name="assetID">Asset UUID to fetch</param> | ||
127 | /// <returns>Return the asset</returns> | ||
128 | /// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks> | ||
129 | public AssetBase GetAsset(UUID assetID) | ||
130 | { | ||
131 | // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); | ||
132 | |||
133 | AssetBase asset = null; | ||
134 | int accessTime = 0; | ||
135 | |||
136 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
137 | { | ||
138 | dbcon.Open(); | ||
139 | |||
140 | using (MySqlCommand cmd = new MySqlCommand( | ||
141 | "SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID", | ||
142 | dbcon)) | ||
143 | { | ||
144 | cmd.Parameters.AddWithValue("?ID", assetID.ToString()); | ||
145 | try | ||
146 | { | ||
147 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
148 | { | ||
149 | if (dbReader.Read()) | ||
150 | { | ||
151 | asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString()); | ||
152 | asset.Data = (byte[])dbReader["Data"]; | ||
153 | asset.Description = (string)dbReader["Description"]; | ||
154 | |||
155 | string local = dbReader["Local"].ToString(); | ||
156 | if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) | ||
157 | asset.Local = true; | ||
158 | else | ||
159 | asset.Local = false; | ||
160 | |||
161 | asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]); | ||
162 | asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); | ||
163 | accessTime = (int)dbReader["AccessTime"]; | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | catch (Exception e) | ||
168 | { | ||
169 | m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e); | ||
170 | } | ||
171 | } | ||
172 | dbcon.Close(); | ||
173 | } | ||
174 | |||
175 | if(asset == null) | ||
176 | return asset; | ||
177 | |||
178 | if(accessTime > 0) | ||
179 | { | ||
180 | try | ||
181 | { | ||
182 | UpdateAccessTime(asset.Metadata, accessTime); | ||
183 | } | ||
184 | catch { } | ||
185 | } | ||
186 | |||
187 | if (m_enableCompression && asset.Data != null) | ||
188 | { | ||
189 | using(MemoryStream ms = new MemoryStream(asset.Data)) | ||
190 | using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress)) | ||
191 | { | ||
192 | using(MemoryStream outputStream = new MemoryStream()) | ||
193 | { | ||
194 | decompressionStream.CopyTo(outputStream, int.MaxValue); | ||
195 | // int compressedLength = asset.Data.Length; | ||
196 | asset.Data = outputStream.ToArray(); | ||
197 | } | ||
198 | // m_log.DebugFormat( | ||
199 | // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", | ||
200 | // asset.ID, asset.Name, asset.Data.Length, compressedLength); | ||
201 | } | ||
202 | } | ||
203 | return asset; | ||
204 | } | ||
205 | |||
206 | /// <summary> | ||
207 | /// Create an asset in database, or update it if existing. | ||
208 | /// </summary> | ||
209 | /// <param name="asset">Asset UUID to create</param> | ||
210 | /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> | ||
211 | public void StoreAsset(AssetBase asset) | ||
212 | { | ||
213 | // m_log.DebugFormat("[XASSETS DB]: Storing asset {0} {1}", asset.Name, asset.ID); | ||
214 | |||
215 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
216 | { | ||
217 | dbcon.Open(); | ||
218 | |||
219 | using (MySqlTransaction transaction = dbcon.BeginTransaction()) | ||
220 | { | ||
221 | string assetName = asset.Name; | ||
222 | if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) | ||
223 | { | ||
224 | assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); | ||
225 | m_log.WarnFormat( | ||
226 | "[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
227 | asset.Name, asset.ID, asset.Name.Length, assetName.Length); | ||
228 | } | ||
229 | |||
230 | string assetDescription = asset.Description; | ||
231 | if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) | ||
232 | { | ||
233 | assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); | ||
234 | m_log.WarnFormat( | ||
235 | "[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
236 | asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); | ||
237 | } | ||
238 | |||
239 | if (m_enableCompression) | ||
240 | { | ||
241 | MemoryStream outputStream = new MemoryStream(); | ||
242 | |||
243 | using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false)) | ||
244 | { | ||
245 | // Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue)); | ||
246 | // We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream. | ||
247 | compressionStream.Close(); | ||
248 | byte[] compressedData = outputStream.ToArray(); | ||
249 | asset.Data = compressedData; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | byte[] hash = hasher.ComputeHash(asset.Data); | ||
254 | |||
255 | // m_log.DebugFormat( | ||
256 | // "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}", | ||
257 | // asset.ID, asset.Name, hash, compressedData.Length); | ||
258 | |||
259 | try | ||
260 | { | ||
261 | using (MySqlCommand cmd = | ||
262 | new MySqlCommand( | ||
263 | "replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" + | ||
264 | "VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)", | ||
265 | dbcon)) | ||
266 | { | ||
267 | // create unix epoch time | ||
268 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
269 | cmd.Parameters.AddWithValue("?ID", asset.ID); | ||
270 | cmd.Parameters.AddWithValue("?Hash", hash); | ||
271 | cmd.Parameters.AddWithValue("?Name", assetName); | ||
272 | cmd.Parameters.AddWithValue("?Description", assetDescription); | ||
273 | cmd.Parameters.AddWithValue("?AssetType", asset.Type); | ||
274 | cmd.Parameters.AddWithValue("?Local", asset.Local); | ||
275 | cmd.Parameters.AddWithValue("?Temporary", asset.Temporary); | ||
276 | cmd.Parameters.AddWithValue("?CreateTime", now); | ||
277 | cmd.Parameters.AddWithValue("?AccessTime", now); | ||
278 | cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); | ||
279 | cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags); | ||
280 | cmd.ExecuteNonQuery(); | ||
281 | } | ||
282 | } | ||
283 | catch (Exception e) | ||
284 | { | ||
285 | m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}", | ||
286 | asset.FullID, asset.Name, e.Message); | ||
287 | |||
288 | transaction.Rollback(); | ||
289 | |||
290 | return; | ||
291 | } | ||
292 | |||
293 | if (!ExistsData(dbcon, transaction, hash)) | ||
294 | { | ||
295 | try | ||
296 | { | ||
297 | using (MySqlCommand cmd = | ||
298 | new MySqlCommand( | ||
299 | "INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)", | ||
300 | dbcon)) | ||
301 | { | ||
302 | cmd.Parameters.AddWithValue("?Hash", hash); | ||
303 | cmd.Parameters.AddWithValue("?Data", asset.Data); | ||
304 | cmd.ExecuteNonQuery(); | ||
305 | } | ||
306 | } | ||
307 | catch (Exception e) | ||
308 | { | ||
309 | m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}", | ||
310 | asset.FullID, asset.Name, e.Message); | ||
311 | |||
312 | transaction.Rollback(); | ||
313 | |||
314 | return; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | transaction.Commit(); | ||
319 | } | ||
320 | dbcon.Close(); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /// <summary> | ||
325 | /// Updates the access time of the asset if it was accessed above a given threshhold amount of time. | ||
326 | /// </summary> | ||
327 | /// <remarks> | ||
328 | /// This gives us some insight into assets which haven't ben accessed for a long period. This is only done | ||
329 | /// over the threshold time to avoid excessive database writes as assets are fetched. | ||
330 | /// </remarks> | ||
331 | /// <param name='asset'></param> | ||
332 | /// <param name='accessTime'></param> | ||
333 | private void UpdateAccessTime(AssetMetadata assetMetadata, int accessTime) | ||
334 | { | ||
335 | DateTime now = DateTime.UtcNow; | ||
336 | |||
337 | if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates) | ||
338 | return; | ||
339 | |||
340 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
341 | { | ||
342 | dbcon.Open(); | ||
343 | MySqlCommand cmd = | ||
344 | new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon); | ||
345 | |||
346 | try | ||
347 | { | ||
348 | using (cmd) | ||
349 | { | ||
350 | // create unix epoch time | ||
351 | cmd.Parameters.AddWithValue("?ID", assetMetadata.ID); | ||
352 | cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now)); | ||
353 | cmd.ExecuteNonQuery(); | ||
354 | } | ||
355 | } | ||
356 | catch (Exception) | ||
357 | { | ||
358 | m_log.ErrorFormat( | ||
359 | "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", | ||
360 | assetMetadata.ID, assetMetadata.Name); | ||
361 | } | ||
362 | dbcon.Close(); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | /// <summary> | ||
367 | /// We assume we already have the m_dbLock. | ||
368 | /// </summary> | ||
369 | /// TODO: need to actually use the transaction. | ||
370 | /// <param name="dbcon"></param> | ||
371 | /// <param name="transaction"></param> | ||
372 | /// <param name="hash"></param> | ||
373 | /// <returns></returns> | ||
374 | private bool ExistsData(MySqlConnection dbcon, MySqlTransaction transaction, byte[] hash) | ||
375 | { | ||
376 | // m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid); | ||
377 | |||
378 | bool exists = false; | ||
379 | |||
380 | using (MySqlCommand cmd = new MySqlCommand("SELECT Hash FROM XAssetsData WHERE Hash=?Hash", dbcon)) | ||
381 | { | ||
382 | cmd.Parameters.AddWithValue("?Hash", hash); | ||
383 | |||
384 | try | ||
385 | { | ||
386 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
387 | { | ||
388 | if (dbReader.Read()) | ||
389 | { | ||
390 | // m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid); | ||
391 | exists = true; | ||
392 | } | ||
393 | } | ||
394 | } | ||
395 | catch (Exception e) | ||
396 | { | ||
397 | m_log.ErrorFormat( | ||
398 | "[XASSETS DB]: MySql failure in ExistsData fetching hash {0}. Exception {1}{2}", | ||
399 | hash, e.Message, e.StackTrace); | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return exists; | ||
404 | } | ||
405 | |||
406 | /// <summary> | ||
407 | /// Check if the assets exist in the database. | ||
408 | /// </summary> | ||
409 | /// <param name="uuids">The asset UUID's</param> | ||
410 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
411 | public bool[] AssetsExist(UUID[] uuids) | ||
412 | { | ||
413 | if (uuids.Length == 0) | ||
414 | return new bool[0]; | ||
415 | |||
416 | HashSet<UUID> exists = new HashSet<UUID>(); | ||
417 | |||
418 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
419 | string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids); | ||
420 | |||
421 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
422 | { | ||
423 | dbcon.Open(); | ||
424 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
425 | { | ||
426 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
427 | { | ||
428 | while (dbReader.Read()) | ||
429 | { | ||
430 | UUID id = DBGuid.FromDB(dbReader["ID"]); | ||
431 | exists.Add(id); | ||
432 | } | ||
433 | } | ||
434 | } | ||
435 | } | ||
436 | |||
437 | bool[] results = new bool[uuids.Length]; | ||
438 | for (int i = 0; i < uuids.Length; i++) | ||
439 | results[i] = exists.Contains(uuids[i]); | ||
440 | return results; | ||
441 | } | ||
442 | |||
443 | |||
444 | /// <summary> | ||
445 | /// Returns a list of AssetMetadata objects. The list is a subset of | ||
446 | /// the entire data set offset by <paramref name="start" /> containing | ||
447 | /// <paramref name="count" /> elements. | ||
448 | /// </summary> | ||
449 | /// <param name="start">The number of results to discard from the total data set.</param> | ||
450 | /// <param name="count">The number of rows the returned list should contain.</param> | ||
451 | /// <returns>A list of AssetMetadata objects.</returns> | ||
452 | public List<AssetMetadata> FetchAssetMetadataSet(int start, int count) | ||
453 | { | ||
454 | List<AssetMetadata> retList = new List<AssetMetadata>(count); | ||
455 | |||
456 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
457 | { | ||
458 | dbcon.Open(); | ||
459 | using(MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count",dbcon)) | ||
460 | { | ||
461 | cmd.Parameters.AddWithValue("?start",start); | ||
462 | cmd.Parameters.AddWithValue("?count", count); | ||
463 | |||
464 | try | ||
465 | { | ||
466 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | ||
467 | { | ||
468 | while (dbReader.Read()) | ||
469 | { | ||
470 | AssetMetadata metadata = new AssetMetadata(); | ||
471 | metadata.Name = (string)dbReader["Name"]; | ||
472 | metadata.Description = (string)dbReader["Description"]; | ||
473 | metadata.Type = (sbyte)dbReader["AssetType"]; | ||
474 | metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct. | ||
475 | metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); | ||
476 | metadata.FullID = DBGuid.FromDB(dbReader["ID"]); | ||
477 | metadata.CreatorID = dbReader["CreatorID"].ToString(); | ||
478 | |||
479 | // We'll ignore this for now - it appears unused! | ||
480 | // metadata.SHA1 = dbReader["hash"]); | ||
481 | |||
482 | UpdateAccessTime(metadata, (int)dbReader["AccessTime"]); | ||
483 | |||
484 | retList.Add(metadata); | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | catch (Exception e) | ||
489 | { | ||
490 | m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); | ||
491 | } | ||
492 | } | ||
493 | dbcon.Close(); | ||
494 | } | ||
495 | |||
496 | return retList; | ||
497 | } | ||
498 | |||
499 | public bool Delete(string id) | ||
500 | { | ||
501 | // m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id); | ||
502 | |||
503 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
504 | { | ||
505 | dbcon.Open(); | ||
506 | |||
507 | using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon)) | ||
508 | { | ||
509 | cmd.Parameters.AddWithValue("?ID", id); | ||
510 | cmd.ExecuteNonQuery(); | ||
511 | } | ||
512 | // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we | ||
513 | // keep a reference count (?) | ||
514 | dbcon.Close(); | ||
515 | } | ||
516 | |||
517 | return true; | ||
518 | } | ||
519 | |||
520 | #endregion | ||
521 | } | ||
522 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs new file mode 100644 index 0000000..5019994 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs | |||
@@ -0,0 +1,339 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1"); | ||
199 | |||
200 | cmd.Parameters.AddWithValue("?uuid", principalID.ToString()); | ||
201 | cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); | ||
202 | |||
203 | return DoQuery(cmd); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | public int GetAssetPermissions(UUID principalID, UUID assetID) | ||
208 | { | ||
209 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
210 | { | ||
211 | dbcon.Open(); | ||
212 | |||
213 | using (MySqlCommand cmd = new MySqlCommand()) | ||
214 | { | ||
215 | cmd.Connection = dbcon; | ||
216 | |||
217 | // cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); | ||
218 | |||
219 | cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID"); | ||
220 | |||
221 | cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); | ||
222 | cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); | ||
223 | |||
224 | using (IDataReader reader = cmd.ExecuteReader()) | ||
225 | { | ||
226 | |||
227 | int perms = 0; | ||
228 | |||
229 | if (reader.Read()) | ||
230 | { | ||
231 | perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); | ||
232 | } | ||
233 | |||
234 | return perms; | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | public override bool Store(XInventoryItem item) | ||
241 | { | ||
242 | if (!base.Store(item)) | ||
243 | return false; | ||
244 | |||
245 | IncrementFolderVersion(item.parentFolderID); | ||
246 | |||
247 | return true; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | public class MySqlFolderHandler : MySqlInventoryHandler<XInventoryFolder> | ||
252 | { | ||
253 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
254 | |||
255 | public MySqlFolderHandler(string c, string t, string m) : | ||
256 | base(c, t, m) | ||
257 | { | ||
258 | } | ||
259 | |||
260 | public bool MoveFolder(string id, string newParentFolderID) | ||
261 | { | ||
262 | XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); | ||
263 | |||
264 | if (folders.Length == 0) | ||
265 | return false; | ||
266 | |||
267 | UUID oldParentFolderUUID = folders[0].parentFolderID; | ||
268 | |||
269 | using (MySqlCommand cmd = new MySqlCommand()) | ||
270 | { | ||
271 | cmd.CommandText | ||
272 | = String.Format( | ||
273 | "update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm); | ||
274 | cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID); | ||
275 | cmd.Parameters.AddWithValue("?folderID", id); | ||
276 | |||
277 | if (ExecuteNonQuery(cmd) == 0) | ||
278 | return false; | ||
279 | } | ||
280 | |||
281 | IncrementFolderVersion(oldParentFolderUUID); | ||
282 | IncrementFolderVersion(newParentFolderID); | ||
283 | |||
284 | return true; | ||
285 | } | ||
286 | |||
287 | public override bool Store(XInventoryFolder folder) | ||
288 | { | ||
289 | if (!base.Store(folder)) | ||
290 | return false; | ||
291 | |||
292 | IncrementFolderVersion(folder.parentFolderID); | ||
293 | |||
294 | return true; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | public class MySqlInventoryHandler<T> : MySQLGenericTableHandler<T> where T: class, new() | ||
299 | { | ||
300 | public MySqlInventoryHandler(string c, string t, string m) : base(c, t, m) {} | ||
301 | |||
302 | protected bool IncrementFolderVersion(UUID folderID) | ||
303 | { | ||
304 | return IncrementFolderVersion(folderID.ToString()); | ||
305 | } | ||
306 | |||
307 | protected bool IncrementFolderVersion(string folderID) | ||
308 | { | ||
309 | // m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID); | ||
310 | // Util.PrintCallStack(); | ||
311 | |||
312 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
313 | { | ||
314 | dbcon.Open(); | ||
315 | |||
316 | using (MySqlCommand cmd = new MySqlCommand()) | ||
317 | { | ||
318 | cmd.Connection = dbcon; | ||
319 | |||
320 | cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID"); | ||
321 | cmd.Parameters.AddWithValue("?folderID", folderID); | ||
322 | |||
323 | try | ||
324 | { | ||
325 | cmd.ExecuteNonQuery(); | ||
326 | } | ||
327 | catch (Exception) | ||
328 | { | ||
329 | return false; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | dbcon.Close(); | ||
334 | } | ||
335 | |||
336 | return true; | ||
337 | } | ||
338 | } | ||
339 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6507a37 --- /dev/null +++ b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
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(OpenSim.VersionInfo.AssemblyVersionNumber)] | ||
65 | |||
diff --git a/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations new file mode 100644 index 0000000..d41ae66 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/AgentPrefs.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | :VERSION 1 # ------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `AgentPrefs` ( | ||
6 | `PrincipalID` CHAR(36) NOT NULL, | ||
7 | `AccessPrefs` CHAR(2) NOT NULL DEFAULT 'M', | ||
8 | `HoverHeight` DOUBLE(30, 27) NOT NULL DEFAULT 0, | ||
9 | `Language` CHAR(5) NOT NULL DEFAULT 'en-us', | ||
10 | `LanguageIsPublic` BOOLEAN NOT NULL DEFAULT 1, | ||
11 | `PermEveryone` INT(6) NOT NULL DEFAULT 0, | ||
12 | `PermGroup` INT(6) NOT NULL DEFAULT 0, | ||
13 | `PermNextOwner` INT(6) NOT NULL DEFAULT 532480, | ||
14 | UNIQUE KEY `PrincipalID` (`PrincipalID`), | ||
15 | PRIMARY KEY(`PrincipalID`) | ||
16 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
17 | |||
18 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/AssetStore.migrations b/OpenSim/Data/MySQL/Resources/AssetStore.migrations new file mode 100644 index 0000000..07f521b --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/AssetStore.migrations | |||
@@ -0,0 +1,21 @@ | |||
1 | # ----------------- | ||
2 | :VERSION 10 | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE IF NOT EXISTS `assets` ( | ||
7 | `name` varchar(64) NOT NULL, | ||
8 | `description` varchar(64) NOT NULL, | ||
9 | `assetType` tinyint(4) NOT NULL, | ||
10 | `local` tinyint(1) NOT NULL, | ||
11 | `temporary` tinyint(1) NOT NULL, | ||
12 | `data` longblob NOT NULL, | ||
13 | `id` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
14 | `create_time` int(11) DEFAULT '0', | ||
15 | `access_time` int(11) DEFAULT '0', | ||
16 | `asset_flags` int(11) NOT NULL DEFAULT '0', | ||
17 | `CreatorID` varchar(128) NOT NULL DEFAULT '', | ||
18 | PRIMARY KEY (`id`) | ||
19 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
20 | |||
21 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/AuthStore.migrations b/OpenSim/Data/MySQL/Resources/AuthStore.migrations new file mode 100644 index 0000000..8d24fbd --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/AuthStore.migrations | |||
@@ -0,0 +1,24 @@ | |||
1 | :VERSION 4 # ------------------------------- | ||
2 | |||
3 | begin; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `auth` ( | ||
6 | `UUID` char(36) NOT NULL, | ||
7 | `passwordHash` char(32) NOT NULL DEFAULT '', | ||
8 | `passwordSalt` char(32) NOT NULL DEFAULT '', | ||
9 | `webLoginKey` varchar(255) NOT NULL DEFAULT '', | ||
10 | `accountType` varchar(32) NOT NULL DEFAULT 'UserAccount', | ||
11 | PRIMARY KEY (`UUID`) | ||
12 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
13 | |||
14 | CREATE TABLE IF NOT EXISTS `tokens` ( | ||
15 | `UUID` char(36) NOT NULL, | ||
16 | `token` varchar(255) NOT NULL, | ||
17 | `validity` datetime NOT NULL, | ||
18 | UNIQUE KEY `uuid_token` (`UUID`,`token`), | ||
19 | KEY `UUID` (`UUID`), | ||
20 | KEY `token` (`token`), | ||
21 | KEY `validity` (`validity`) | ||
22 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
23 | |||
24 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/Avatar.migrations b/OpenSim/Data/MySQL/Resources/Avatar.migrations new file mode 100644 index 0000000..66f75b2 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/Avatar.migrations | |||
@@ -0,0 +1,13 @@ | |||
1 | :VERSION 3 | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `Avatars` ( | ||
6 | `PrincipalID` char(36) NOT NULL, | ||
7 | `Name` varchar(32) NOT NULL, | ||
8 | `Value` text, | ||
9 | PRIMARY KEY (`PrincipalID`,`Name`), | ||
10 | KEY `PrincipalID` (`PrincipalID`) | ||
11 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
12 | |||
13 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/EstateStore.migrations b/OpenSim/Data/MySQL/Resources/EstateStore.migrations new file mode 100644 index 0000000..9c1ed83 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/EstateStore.migrations | |||
@@ -0,0 +1,71 @@ | |||
1 | :VERSION 34 | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `estate_groups` ( | ||
6 | `EstateID` int(10) unsigned NOT NULL, | ||
7 | `uuid` char(36) NOT NULL, | ||
8 | KEY `EstateID` (`EstateID`) | ||
9 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
10 | |||
11 | CREATE TABLE IF NOT EXISTS `estate_managers` ( | ||
12 | `EstateID` int(10) unsigned NOT NULL, | ||
13 | `uuid` char(36) NOT NULL, | ||
14 | KEY `EstateID` (`EstateID`) | ||
15 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
16 | |||
17 | CREATE TABLE IF NOT EXISTS `estate_map` ( | ||
18 | `RegionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
19 | `EstateID` int(11) NOT NULL, | ||
20 | PRIMARY KEY (`RegionID`), | ||
21 | KEY `EstateID` (`EstateID`) | ||
22 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
23 | |||
24 | CREATE TABLE IF NOT EXISTS `estate_settings` ( | ||
25 | `EstateID` int(10) unsigned NOT NULL AUTO_INCREMENT, | ||
26 | `EstateName` varchar(64) DEFAULT NULL, | ||
27 | `AbuseEmailToEstateOwner` tinyint(4) NOT NULL, | ||
28 | `DenyAnonymous` tinyint(4) NOT NULL, | ||
29 | `ResetHomeOnTeleport` tinyint(4) NOT NULL, | ||
30 | `FixedSun` tinyint(4) NOT NULL, | ||
31 | `DenyTransacted` tinyint(4) NOT NULL, | ||
32 | `BlockDwell` tinyint(4) NOT NULL, | ||
33 | `DenyIdentified` tinyint(4) NOT NULL, | ||
34 | `AllowVoice` tinyint(4) NOT NULL, | ||
35 | `UseGlobalTime` tinyint(4) NOT NULL, | ||
36 | `PricePerMeter` int(11) NOT NULL, | ||
37 | `TaxFree` tinyint(4) NOT NULL, | ||
38 | `AllowDirectTeleport` tinyint(4) NOT NULL, | ||
39 | `RedirectGridX` int(11) NOT NULL, | ||
40 | `RedirectGridY` int(11) NOT NULL, | ||
41 | `ParentEstateID` int(10) unsigned NOT NULL, | ||
42 | `SunPosition` double NOT NULL, | ||
43 | `EstateSkipScripts` tinyint(4) NOT NULL, | ||
44 | `BillableFactor` float NOT NULL, | ||
45 | `PublicAccess` tinyint(4) NOT NULL, | ||
46 | `AbuseEmail` varchar(255) NOT NULL, | ||
47 | `EstateOwner` varchar(36) NOT NULL, | ||
48 | `DenyMinors` tinyint(4) NOT NULL, | ||
49 | `AllowLandmark` tinyint(4) NOT NULL DEFAULT '1', | ||
50 | `AllowParcelChanges` tinyint(4) NOT NULL DEFAULT '1', | ||
51 | `AllowSetHome` tinyint(4) NOT NULL DEFAULT '1', | ||
52 | PRIMARY KEY (`EstateID`) | ||
53 | ) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=utf8; | ||
54 | |||
55 | CREATE TABLE IF NOT EXISTS `estate_users` ( | ||
56 | `EstateID` int(10) unsigned NOT NULL, | ||
57 | `uuid` char(36) NOT NULL, | ||
58 | KEY `EstateID` (`EstateID`) | ||
59 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
60 | |||
61 | CREATE TABLE IF NOT EXISTS `estateban` ( | ||
62 | `EstateID` int(10) unsigned NOT NULL, | ||
63 | `bannedUUID` varchar(36) NOT NULL, | ||
64 | `bannedIp` varchar(16) NOT NULL, | ||
65 | `bannedIpHostMask` varchar(16) NOT NULL, | ||
66 | `bannedNameMask` varchar(64) DEFAULT NULL, | ||
67 | KEY `estateban_EstateID` (`EstateID`) | ||
68 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
69 | |||
70 | COMMIT; | ||
71 | |||
diff --git a/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations new file mode 100644 index 0000000..3f65d9e --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/FSAssetStore.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | # ----------------- | ||
2 | :VERSION 1 | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE IF NOT EXISTS `fsassets` ( | ||
7 | `id` char(36) NOT NULL, | ||
8 | `name` varchar(64) NOT NULL DEFAULT '', | ||
9 | `description` varchar(64) NOT NULL DEFAULT '', | ||
10 | `type` int(11) NOT NULL, | ||
11 | `hash` char(80) NOT NULL, | ||
12 | `create_time` int(11) NOT NULL DEFAULT '0', | ||
13 | `access_time` int(11) NOT NULL DEFAULT '0', | ||
14 | `asset_flags` int(11) NOT NULL DEFAULT '0', | ||
15 | PRIMARY KEY (`id`) | ||
16 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
17 | |||
18 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations new file mode 100644 index 0000000..7dc7607 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations | |||
@@ -0,0 +1,14 @@ | |||
1 | :VERSION 4 # ------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `Friends` ( | ||
6 | `PrincipalID` varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
7 | `Friend` varchar(255) NOT NULL, | ||
8 | `Flags` varchar(16) NOT NULL DEFAULT '0', | ||
9 | `Offered` varchar(32) NOT NULL DEFAULT '0', | ||
10 | PRIMARY KEY (`PrincipalID`(36),`Friend`(36)), | ||
11 | KEY `PrincipalID` (`PrincipalID`) | ||
12 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
13 | |||
14 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/GridStore.migrations b/OpenSim/Data/MySQL/Resources/GridStore.migrations new file mode 100644 index 0000000..4116235 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/GridStore.migrations | |||
@@ -0,0 +1,52 @@ | |||
1 | :VERSION 10 | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `regions` ( | ||
6 | `uuid` varchar(36) NOT NULL, | ||
7 | `regionHandle` bigint(20) unsigned NOT NULL, | ||
8 | `regionName` varchar(128) DEFAULT NULL, | ||
9 | `regionRecvKey` varchar(128) DEFAULT NULL, | ||
10 | `regionSendKey` varchar(128) DEFAULT NULL, | ||
11 | `regionSecret` varchar(128) DEFAULT NULL, | ||
12 | `regionDataURI` varchar(255) DEFAULT NULL, | ||
13 | `serverIP` varchar(64) DEFAULT NULL, | ||
14 | `serverPort` int(10) unsigned DEFAULT NULL, | ||
15 | `serverURI` varchar(255) DEFAULT NULL, | ||
16 | `locX` int(10) unsigned DEFAULT NULL, | ||
17 | `locY` int(10) unsigned DEFAULT NULL, | ||
18 | `locZ` int(10) unsigned DEFAULT NULL, | ||
19 | `eastOverrideHandle` bigint(20) unsigned DEFAULT NULL, | ||
20 | `westOverrideHandle` bigint(20) unsigned DEFAULT NULL, | ||
21 | `southOverrideHandle` bigint(20) unsigned DEFAULT NULL, | ||
22 | `northOverrideHandle` bigint(20) unsigned DEFAULT NULL, | ||
23 | `regionAssetURI` varchar(255) DEFAULT NULL, | ||
24 | `regionAssetRecvKey` varchar(128) DEFAULT NULL, | ||
25 | `regionAssetSendKey` varchar(128) DEFAULT NULL, | ||
26 | `regionUserURI` varchar(255) DEFAULT NULL, | ||
27 | `regionUserRecvKey` varchar(128) DEFAULT NULL, | ||
28 | `regionUserSendKey` varchar(128) DEFAULT NULL, | ||
29 | `regionMapTexture` varchar(36) DEFAULT NULL, | ||
30 | `serverHttpPort` int(10) DEFAULT NULL, | ||
31 | `serverRemotingPort` int(10) DEFAULT NULL, | ||
32 | `owner_uuid` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
33 | `originUUID` varchar(36) DEFAULT NULL, | ||
34 | `access` int(10) unsigned DEFAULT '1', | ||
35 | `ScopeID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
36 | `sizeX` int(11) NOT NULL DEFAULT '0', | ||
37 | `sizeY` int(11) NOT NULL DEFAULT '0', | ||
38 | `flags` int(11) NOT NULL DEFAULT '0', | ||
39 | `last_seen` int(11) NOT NULL DEFAULT '0', | ||
40 | `PrincipalID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
41 | `Token` varchar(255) NOT NULL, | ||
42 | `parcelMapTexture` varchar(36) DEFAULT NULL, | ||
43 | PRIMARY KEY (`uuid`), | ||
44 | KEY `regionName` (`regionName`), | ||
45 | KEY `regionHandle` (`regionHandle`), | ||
46 | KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`), | ||
47 | KEY `ScopeID` (`ScopeID`), | ||
48 | KEY `flags` (`flags`) | ||
49 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
50 | |||
51 | COMMIT; | ||
52 | |||
diff --git a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations new file mode 100644 index 0000000..dd73974 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations | |||
@@ -0,0 +1,19 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `GridUser` ( | ||
6 | `UserID` VARCHAR(255) NOT NULL, | ||
7 | `HomeRegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
8 | `HomePosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
9 | `HomeLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
10 | `LastRegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
11 | `LastPosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
12 | `LastLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
13 | `Online` CHAR(5) NOT NULL DEFAULT 'false', | ||
14 | `Login` CHAR(16) NOT NULL DEFAULT '0', | ||
15 | `Logout` CHAR(16) NOT NULL DEFAULT '0', | ||
16 | PRIMARY KEY (`UserID`) | ||
17 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
18 | |||
19 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations new file mode 100644 index 0000000..ed1fede --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations | |||
@@ -0,0 +1,17 @@ | |||
1 | :VERSION 1 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `hg_traveling_data` ( | ||
6 | `SessionID` VARCHAR(36) NOT NULL, | ||
7 | `UserID` VARCHAR(36) NOT NULL, | ||
8 | `GridExternalName` VARCHAR(255) NOT NULL DEFAULT '', | ||
9 | `ServiceToken` VARCHAR(255) NOT NULL DEFAULT '', | ||
10 | `ClientIPAddress` VARCHAR(16) NOT NULL DEFAULT '', | ||
11 | `MyIPAddress` VARCHAR(16) NOT NULL DEFAULT '', | ||
12 | `TMStamp` timestamp NOT NULL, | ||
13 | PRIMARY KEY (`SessionID`), | ||
14 | KEY (`UserID`) | ||
15 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
16 | |||
17 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/IM_Store.migrations b/OpenSim/Data/MySQL/Resources/IM_Store.migrations new file mode 100644 index 0000000..e271fcc --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/IM_Store.migrations | |||
@@ -0,0 +1,16 @@ | |||
1 | :VERSION 5 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `im_offline` ( | ||
6 | `ID` mediumint(9) NOT NULL AUTO_INCREMENT, | ||
7 | `PrincipalID` char(36) NOT NULL DEFAULT '', | ||
8 | `FromID` char(36) NOT NULL DEFAULT '', | ||
9 | `Message` text NOT NULL, | ||
10 | `TMStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | ||
11 | PRIMARY KEY (`ID`), | ||
12 | KEY `PrincipalID` (`PrincipalID`), | ||
13 | KEY `FromID` (`FromID`) | ||
14 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
15 | |||
16 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/InventoryStore.migrations b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations new file mode 100644 index 0000000..7283e41 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/InventoryStore.migrations | |||
@@ -0,0 +1,42 @@ | |||
1 | :VERSION 7 # ------------ | ||
2 | BEGIN; | ||
3 | |||
4 | CREATE TABLE IF NOT EXISTS `inventoryitems` ( | ||
5 | `assetID` varchar(36) DEFAULT NULL, | ||
6 | `assetType` int(11) DEFAULT NULL, | ||
7 | `inventoryName` varchar(64) DEFAULT NULL, | ||
8 | `inventoryDescription` varchar(128) DEFAULT NULL, | ||
9 | `inventoryNextPermissions` int(10) unsigned DEFAULT NULL, | ||
10 | `inventoryCurrentPermissions` int(10) unsigned DEFAULT NULL, | ||
11 | `invType` int(11) DEFAULT NULL, | ||
12 | `creatorID` varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
13 | `inventoryBasePermissions` int(10) unsigned NOT NULL DEFAULT '0', | ||
14 | `inventoryEveryOnePermissions` int(10) unsigned NOT NULL DEFAULT '0', | ||
15 | `salePrice` int(11) NOT NULL DEFAULT '0', | ||
16 | `saleType` tinyint(4) NOT NULL DEFAULT '0', | ||
17 | `creationDate` int(11) NOT NULL DEFAULT '0', | ||
18 | `groupID` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
19 | `groupOwned` tinyint(4) NOT NULL DEFAULT '0', | ||
20 | `flags` int(11) unsigned NOT NULL DEFAULT '0', | ||
21 | `inventoryID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
22 | `avatarID` char(36) DEFAULT NULL, | ||
23 | `parentFolderID` char(36) DEFAULT NULL, | ||
24 | `inventoryGroupPermissions` int(10) unsigned NOT NULL DEFAULT '0', | ||
25 | PRIMARY KEY (`inventoryID`), | ||
26 | KEY `inventoryitems_avatarid` (`avatarID`), | ||
27 | KEY `inventoryitems_parentFolderid` (`parentFolderID`) | ||
28 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
29 | |||
30 | CREATE TABLE IF NOT EXISTS `inventoryfolders` ( | ||
31 | `folderName` varchar(64) DEFAULT NULL, | ||
32 | `type` smallint(6) NOT NULL DEFAULT '0', | ||
33 | `version` int(11) NOT NULL DEFAULT '0', | ||
34 | `folderID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
35 | `agentID` char(36) DEFAULT NULL, | ||
36 | `parentFolderID` char(36) DEFAULT NULL, | ||
37 | PRIMARY KEY (`folderID`), | ||
38 | KEY `inventoryfolders_agentid` (`agentID`), | ||
39 | KEY `inventoryfolders_parentFolderid` (`parentFolderID`) | ||
40 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
41 | |||
42 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/LogStore.migrations b/OpenSim/Data/MySQL/Resources/LogStore.migrations new file mode 100644 index 0000000..f2990cc --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/LogStore.migrations | |||
@@ -0,0 +1,13 @@ | |||
1 | | ||
2 | :VERSION 1 | ||
3 | |||
4 | CREATE TABLE IF NOT EXISTS `logs` ( | ||
5 | `logID` int(10) unsigned NOT NULL auto_increment, | ||
6 | `target` varchar(36) default NULL, | ||
7 | `server` varchar(64) default NULL, | ||
8 | `method` varchar(64) default NULL, | ||
9 | `arguments` varchar(255) default NULL, | ||
10 | `priority` int(11) default NULL, | ||
11 | `message` text, | ||
12 | PRIMARY KEY (`logID`) | ||
13 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
diff --git a/OpenSim/Data/MySQL/Resources/MuteListStore.migrations b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations new file mode 100644 index 0000000..164dc51 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations | |||
@@ -0,0 +1,16 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `MuteList` ( | ||
6 | `AgentID` char(36) NOT NULL, | ||
7 | `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
8 | `MuteName` varchar(64) NOT NULL DEFAULT '', | ||
9 | `MuteType` int(11) NOT NULL DEFAULT '1', | ||
10 | `MuteFlags` int(11) NOT NULL DEFAULT '0', | ||
11 | `Stamp` int(11) NOT NULL, | ||
12 | UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`), | ||
13 | KEY `AgentID` (`AgentID`) | ||
14 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
15 | |||
16 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations new file mode 100644 index 0000000..4d14b9d --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/Presence.migrations | |||
@@ -0,0 +1,16 @@ | |||
1 | :VERSION 4 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `Presence` ( | ||
6 | `UserID` varchar(255) NOT NULL, | ||
7 | `RegionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
8 | `SessionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
9 | `SecureSessionID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
10 | `LastSeen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | ||
11 | UNIQUE KEY `SessionID` (`SessionID`), | ||
12 | KEY `UserID` (`UserID`), | ||
13 | KEY `RegionID` (`RegionID`) | ||
14 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
15 | |||
16 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations new file mode 100644 index 0000000..fb7862a --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations | |||
@@ -0,0 +1,469 @@ | |||
1 | |||
2 | :VERSION 51 #--------------------- | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE IF NOT EXISTS `prims` ( | ||
7 | `CreationDate` int(11) DEFAULT NULL, | ||
8 | `Name` varchar(255) DEFAULT NULL, | ||
9 | `Text` varchar(255) DEFAULT NULL, | ||
10 | `Description` varchar(255) DEFAULT NULL, | ||
11 | `SitName` varchar(255) DEFAULT NULL, | ||
12 | `TouchName` varchar(255) DEFAULT NULL, | ||
13 | `ObjectFlags` int(11) DEFAULT NULL, | ||
14 | `OwnerMask` int(11) DEFAULT NULL, | ||
15 | `NextOwnerMask` int(11) DEFAULT NULL, | ||
16 | `GroupMask` int(11) DEFAULT NULL, | ||
17 | `EveryoneMask` int(11) DEFAULT NULL, | ||
18 | `BaseMask` int(11) DEFAULT NULL, | ||
19 | `PositionX` double DEFAULT NULL, | ||
20 | `PositionY` double DEFAULT NULL, | ||
21 | `PositionZ` double DEFAULT NULL, | ||
22 | `GroupPositionX` double DEFAULT NULL, | ||
23 | `GroupPositionY` double DEFAULT NULL, | ||
24 | `GroupPositionZ` double DEFAULT NULL, | ||
25 | `VelocityX` double DEFAULT NULL, | ||
26 | `VelocityY` double DEFAULT NULL, | ||
27 | `VelocityZ` double DEFAULT NULL, | ||
28 | `AngularVelocityX` double DEFAULT NULL, | ||
29 | `AngularVelocityY` double DEFAULT NULL, | ||
30 | `AngularVelocityZ` double DEFAULT NULL, | ||
31 | `AccelerationX` double DEFAULT NULL, | ||
32 | `AccelerationY` double DEFAULT NULL, | ||
33 | `AccelerationZ` double DEFAULT NULL, | ||
34 | `RotationX` double DEFAULT NULL, | ||
35 | `RotationY` double DEFAULT NULL, | ||
36 | `RotationZ` double DEFAULT NULL, | ||
37 | `RotationW` double DEFAULT NULL, | ||
38 | `SitTargetOffsetX` double DEFAULT NULL, | ||
39 | `SitTargetOffsetY` double DEFAULT NULL, | ||
40 | `SitTargetOffsetZ` double DEFAULT NULL, | ||
41 | `SitTargetOrientW` double DEFAULT NULL, | ||
42 | `SitTargetOrientX` double DEFAULT NULL, | ||
43 | `SitTargetOrientY` double DEFAULT NULL, | ||
44 | `SitTargetOrientZ` double DEFAULT NULL, | ||
45 | `UUID` char(36) NOT NULL DEFAULT '', | ||
46 | `RegionUUID` char(36) DEFAULT NULL, | ||
47 | `CreatorID` varchar(255) NOT NULL DEFAULT '', | ||
48 | `OwnerID` char(36) DEFAULT NULL, | ||
49 | `GroupID` char(36) DEFAULT NULL, | ||
50 | `LastOwnerID` char(36) DEFAULT NULL, | ||
51 | `SceneGroupID` char(36) DEFAULT NULL, | ||
52 | `PayPrice` int(11) NOT NULL DEFAULT '0', | ||
53 | `PayButton1` int(11) NOT NULL DEFAULT '0', | ||
54 | `PayButton2` int(11) NOT NULL DEFAULT '0', | ||
55 | `PayButton3` int(11) NOT NULL DEFAULT '0', | ||
56 | `PayButton4` int(11) NOT NULL DEFAULT '0', | ||
57 | `LoopedSound` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
58 | `LoopedSoundGain` double NOT NULL DEFAULT '0', | ||
59 | `TextureAnimation` blob, | ||
60 | `OmegaX` double NOT NULL DEFAULT '0', | ||
61 | `OmegaY` double NOT NULL DEFAULT '0', | ||
62 | `OmegaZ` double NOT NULL DEFAULT '0', | ||
63 | `CameraEyeOffsetX` double NOT NULL DEFAULT '0', | ||
64 | `CameraEyeOffsetY` double NOT NULL DEFAULT '0', | ||
65 | `CameraEyeOffsetZ` double NOT NULL DEFAULT '0', | ||
66 | `CameraAtOffsetX` double NOT NULL DEFAULT '0', | ||
67 | `CameraAtOffsetY` double NOT NULL DEFAULT '0', | ||
68 | `CameraAtOffsetZ` double NOT NULL DEFAULT '0', | ||
69 | `ForceMouselook` tinyint(4) NOT NULL DEFAULT '0', | ||
70 | `ScriptAccessPin` int(11) NOT NULL DEFAULT '0', | ||
71 | `AllowedDrop` tinyint(4) NOT NULL DEFAULT '0', | ||
72 | `DieAtEdge` tinyint(4) NOT NULL DEFAULT '0', | ||
73 | `SalePrice` int(11) NOT NULL DEFAULT '10', | ||
74 | `SaleType` tinyint(4) NOT NULL DEFAULT '0', | ||
75 | `ColorR` int(11) NOT NULL DEFAULT '0', | ||
76 | `ColorG` int(11) NOT NULL DEFAULT '0', | ||
77 | `ColorB` int(11) NOT NULL DEFAULT '0', | ||
78 | `ColorA` int(11) NOT NULL DEFAULT '0', | ||
79 | `ParticleSystem` blob, | ||
80 | `ClickAction` tinyint(4) NOT NULL DEFAULT '0', | ||
81 | `Material` tinyint(4) NOT NULL DEFAULT '3', | ||
82 | `CollisionSound` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
83 | `CollisionSoundVolume` double NOT NULL DEFAULT '0', | ||
84 | `LinkNumber` int(11) NOT NULL DEFAULT '0', | ||
85 | `PassTouches` tinyint(4) NOT NULL DEFAULT '0', | ||
86 | `MediaURL` varchar(255) DEFAULT NULL, | ||
87 | `DynAttrs` text, | ||
88 | `PhysicsShapeType` tinyint(4) NOT NULL DEFAULT '0', | ||
89 | `Density` double NOT NULL DEFAULT '1000', | ||
90 | `GravityModifier` double NOT NULL DEFAULT '1', | ||
91 | `Friction` double NOT NULL DEFAULT '0.6', | ||
92 | `Restitution` double NOT NULL DEFAULT '0.5', | ||
93 | `KeyframeMotion` blob, | ||
94 | `AttachedPosX` double DEFAULT '0', | ||
95 | `AttachedPosY` double DEFAULT '0', | ||
96 | `AttachedPosZ` double DEFAULT '0', | ||
97 | PRIMARY KEY (`UUID`), | ||
98 | KEY `prims_regionuuid` (`RegionUUID`), | ||
99 | KEY `prims_scenegroupid` (`SceneGroupID`) | ||
100 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
101 | |||
102 | CREATE TABLE IF NOT EXISTS `primshapes` ( | ||
103 | `Shape` int(11) DEFAULT NULL, | ||
104 | `ScaleX` double NOT NULL DEFAULT '0', | ||
105 | `ScaleY` double NOT NULL DEFAULT '0', | ||
106 | `ScaleZ` double NOT NULL DEFAULT '0', | ||
107 | `PCode` int(11) DEFAULT NULL, | ||
108 | `PathBegin` int(11) DEFAULT NULL, | ||
109 | `PathEnd` int(11) DEFAULT NULL, | ||
110 | `PathScaleX` int(11) DEFAULT NULL, | ||
111 | `PathScaleY` int(11) DEFAULT NULL, | ||
112 | `PathShearX` int(11) DEFAULT NULL, | ||
113 | `PathShearY` int(11) DEFAULT NULL, | ||
114 | `PathSkew` int(11) DEFAULT NULL, | ||
115 | `PathCurve` int(11) DEFAULT NULL, | ||
116 | `PathRadiusOffset` int(11) DEFAULT NULL, | ||
117 | `PathRevolutions` int(11) DEFAULT NULL, | ||
118 | `PathTaperX` int(11) DEFAULT NULL, | ||
119 | `PathTaperY` int(11) DEFAULT NULL, | ||
120 | `PathTwist` int(11) DEFAULT NULL, | ||
121 | `PathTwistBegin` int(11) DEFAULT NULL, | ||
122 | `ProfileBegin` int(11) DEFAULT NULL, | ||
123 | `ProfileEnd` int(11) DEFAULT NULL, | ||
124 | `ProfileCurve` int(11) DEFAULT NULL, | ||
125 | `ProfileHollow` int(11) DEFAULT NULL, | ||
126 | `State` int(11) DEFAULT NULL, | ||
127 | `Texture` longblob, | ||
128 | `ExtraParams` longblob, | ||
129 | `UUID` char(36) NOT NULL DEFAULT '', | ||
130 | `Media` text, | ||
131 | `LastAttachPoint` int(4) NOT NULL DEFAULT '0', | ||
132 | PRIMARY KEY (`UUID`) | ||
133 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
134 | |||
135 | CREATE TABLE IF NOT EXISTS `primitems` ( | ||
136 | `invType` int(11) DEFAULT NULL, | ||
137 | `assetType` int(11) DEFAULT NULL, | ||
138 | `name` varchar(255) DEFAULT NULL, | ||
139 | `description` varchar(255) DEFAULT NULL, | ||
140 | `creationDate` bigint(20) DEFAULT NULL, | ||
141 | `nextPermissions` int(11) DEFAULT NULL, | ||
142 | `currentPermissions` int(11) DEFAULT NULL, | ||
143 | `basePermissions` int(11) DEFAULT NULL, | ||
144 | `everyonePermissions` int(11) DEFAULT NULL, | ||
145 | `groupPermissions` int(11) DEFAULT NULL, | ||
146 | `flags` int(11) NOT NULL DEFAULT '0', | ||
147 | `itemID` char(36) NOT NULL DEFAULT '', | ||
148 | `primID` char(36) DEFAULT NULL, | ||
149 | `assetID` char(36) DEFAULT NULL, | ||
150 | `parentFolderID` char(36) DEFAULT NULL, | ||
151 | `CreatorID` varchar(255) NOT NULL DEFAULT '', | ||
152 | `ownerID` char(36) DEFAULT NULL, | ||
153 | `groupID` char(36) DEFAULT NULL, | ||
154 | `lastOwnerID` char(36) DEFAULT NULL, | ||
155 | PRIMARY KEY (`itemID`), | ||
156 | KEY `primitems_primid` (`primID`) | ||
157 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
158 | |||
159 | CREATE TABLE IF NOT EXISTS `terrain` ( | ||
160 | `RegionUUID` varchar(255) DEFAULT NULL, | ||
161 | `Revision` int(11) DEFAULT NULL, | ||
162 | `Heightfield` longblob | ||
163 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
164 | |||
165 | CREATE TABLE IF NOT EXISTS `land` ( | ||
166 | `UUID` varchar(255) NOT NULL, | ||
167 | `RegionUUID` varchar(255) DEFAULT NULL, | ||
168 | `LocalLandID` int(11) DEFAULT NULL, | ||
169 | `Bitmap` longblob, | ||
170 | `Name` varchar(255) DEFAULT NULL, | ||
171 | `Description` varchar(255) DEFAULT NULL, | ||
172 | `OwnerUUID` varchar(255) DEFAULT NULL, | ||
173 | `IsGroupOwned` int(11) DEFAULT NULL, | ||
174 | `Area` int(11) DEFAULT NULL, | ||
175 | `AuctionID` int(11) DEFAULT NULL, | ||
176 | `Category` int(11) DEFAULT NULL, | ||
177 | `ClaimDate` int(11) DEFAULT NULL, | ||
178 | `ClaimPrice` int(11) DEFAULT NULL, | ||
179 | `GroupUUID` varchar(255) DEFAULT NULL, | ||
180 | `SalePrice` int(11) DEFAULT NULL, | ||
181 | `LandStatus` int(11) DEFAULT NULL, | ||
182 | `LandFlags` int(10) unsigned DEFAULT NULL, | ||
183 | `LandingType` int(11) DEFAULT NULL, | ||
184 | `MediaAutoScale` int(11) DEFAULT NULL, | ||
185 | `MediaTextureUUID` varchar(255) DEFAULT NULL, | ||
186 | `MediaURL` varchar(255) DEFAULT NULL, | ||
187 | `MusicURL` varchar(255) DEFAULT NULL, | ||
188 | `PassHours` float DEFAULT NULL, | ||
189 | `PassPrice` int(11) DEFAULT NULL, | ||
190 | `SnapshotUUID` varchar(255) DEFAULT NULL, | ||
191 | `UserLocationX` float DEFAULT NULL, | ||
192 | `UserLocationY` float DEFAULT NULL, | ||
193 | `UserLocationZ` float DEFAULT NULL, | ||
194 | `UserLookAtX` float DEFAULT NULL, | ||
195 | `UserLookAtY` float DEFAULT NULL, | ||
196 | `UserLookAtZ` float DEFAULT NULL, | ||
197 | `AuthbuyerID` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
198 | `OtherCleanTime` int(11) NOT NULL DEFAULT '0', | ||
199 | `Dwell` int(11) NOT NULL DEFAULT '0', | ||
200 | `MediaType` varchar(32) NOT NULL DEFAULT 'none/none', | ||
201 | `MediaDescription` varchar(255) NOT NULL DEFAULT '', | ||
202 | `MediaSize` varchar(16) NOT NULL DEFAULT '0,0', | ||
203 | `MediaLoop` tinyint(1) NOT NULL DEFAULT '0', | ||
204 | `ObscureMusic` tinyint(1) NOT NULL DEFAULT '0', | ||
205 | `ObscureMedia` tinyint(1) NOT NULL DEFAULT '0', | ||
206 | PRIMARY KEY (`UUID`) | ||
207 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
208 | |||
209 | CREATE TABLE IF NOT EXISTS `landaccesslist` ( | ||
210 | `LandUUID` varchar(255) DEFAULT NULL, | ||
211 | `AccessUUID` varchar(255) DEFAULT NULL, | ||
212 | `Flags` int(11) DEFAULT NULL, | ||
213 | `Expires` int(11) NOT NULL DEFAULT '0' | ||
214 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
215 | |||
216 | CREATE TABLE IF NOT EXISTS `regionban` ( | ||
217 | `regionUUID` varchar(36) NOT NULL, | ||
218 | `bannedUUID` varchar(36) NOT NULL, | ||
219 | `bannedIp` varchar(16) NOT NULL, | ||
220 | `bannedIpHostMask` varchar(16) NOT NULL | ||
221 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
222 | |||
223 | CREATE TABLE IF NOT EXISTS `regionsettings` ( | ||
224 | `regionUUID` char(36) NOT NULL, | ||
225 | `block_terraform` int(11) NOT NULL, | ||
226 | `block_fly` int(11) NOT NULL, | ||
227 | `allow_damage` int(11) NOT NULL, | ||
228 | `restrict_pushing` int(11) NOT NULL, | ||
229 | `allow_land_resell` int(11) NOT NULL, | ||
230 | `allow_land_join_divide` int(11) NOT NULL, | ||
231 | `block_show_in_search` int(11) NOT NULL, | ||
232 | `agent_limit` int(11) NOT NULL, | ||
233 | `object_bonus` double NOT NULL, | ||
234 | `maturity` int(11) NOT NULL, | ||
235 | `disable_scripts` int(11) NOT NULL, | ||
236 | `disable_collisions` int(11) NOT NULL, | ||
237 | `disable_physics` int(11) NOT NULL, | ||
238 | `terrain_texture_1` char(36) NOT NULL, | ||
239 | `terrain_texture_2` char(36) NOT NULL, | ||
240 | `terrain_texture_3` char(36) NOT NULL, | ||
241 | `terrain_texture_4` char(36) NOT NULL, | ||
242 | `elevation_1_nw` double NOT NULL, | ||
243 | `elevation_2_nw` double NOT NULL, | ||
244 | `elevation_1_ne` double NOT NULL, | ||
245 | `elevation_2_ne` double NOT NULL, | ||
246 | `elevation_1_se` double NOT NULL, | ||
247 | `elevation_2_se` double NOT NULL, | ||
248 | `elevation_1_sw` double NOT NULL, | ||
249 | `elevation_2_sw` double NOT NULL, | ||
250 | `water_height` double NOT NULL, | ||
251 | `terrain_raise_limit` double NOT NULL, | ||
252 | `terrain_lower_limit` double NOT NULL, | ||
253 | `use_estate_sun` int(11) NOT NULL, | ||
254 | `fixed_sun` int(11) NOT NULL, | ||
255 | `sun_position` double NOT NULL, | ||
256 | `covenant` char(36) DEFAULT NULL, | ||
257 | `Sandbox` tinyint(4) NOT NULL, | ||
258 | `sunvectorx` double NOT NULL DEFAULT '0', | ||
259 | `sunvectory` double NOT NULL DEFAULT '0', | ||
260 | `sunvectorz` double NOT NULL DEFAULT '0', | ||
261 | `loaded_creation_id` varchar(64) DEFAULT NULL, | ||
262 | `loaded_creation_datetime` int(10) unsigned NOT NULL DEFAULT '0', | ||
263 | `map_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
264 | `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
265 | `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
266 | `covenant_datetime` int(10) unsigned NOT NULL DEFAULT '0', | ||
267 | PRIMARY KEY (`regionUUID`) | ||
268 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
269 | |||
270 | CREATE TABLE IF NOT EXISTS `regionwindlight` ( | ||
271 | `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', | ||
272 | `water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000', | ||
273 | `water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000', | ||
274 | `water_color_b` float(9,6) unsigned NOT NULL DEFAULT '64.000000', | ||
275 | `water_fog_density_exponent` float(3,1) unsigned NOT NULL DEFAULT '4.0', | ||
276 | `underwater_fog_modifier` float(3,2) unsigned NOT NULL DEFAULT '0.25', | ||
277 | `reflection_wavelet_scale_1` float(3,1) unsigned NOT NULL DEFAULT '2.0', | ||
278 | `reflection_wavelet_scale_2` float(3,1) unsigned NOT NULL DEFAULT '2.0', | ||
279 | `reflection_wavelet_scale_3` float(3,1) unsigned NOT NULL DEFAULT '2.0', | ||
280 | `fresnel_scale` float(3,2) unsigned NOT NULL DEFAULT '0.40', | ||
281 | `fresnel_offset` float(3,2) unsigned NOT NULL DEFAULT '0.50', | ||
282 | `refract_scale_above` float(3,2) unsigned NOT NULL DEFAULT '0.03', | ||
283 | `refract_scale_below` float(3,2) unsigned NOT NULL DEFAULT '0.20', | ||
284 | `blur_multiplier` float(4,3) unsigned NOT NULL DEFAULT '0.040', | ||
285 | `big_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.05', | ||
286 | `big_wave_direction_y` float(3,2) NOT NULL DEFAULT '-0.42', | ||
287 | `little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11', | ||
288 | `little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16', | ||
289 | `normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4', | ||
290 | `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.25', | ||
291 | `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.25', | ||
292 | `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.32', | ||
293 | `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.32', | ||
294 | `haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19', | ||
295 | `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.12', | ||
296 | `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.22', | ||
297 | `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.38', | ||
298 | `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.38', | ||
299 | `haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70', | ||
300 | `density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18', | ||
301 | `distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8', | ||
302 | `max_altitude` int(4) unsigned NOT NULL DEFAULT '1605', | ||
303 | `sun_moon_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.24', | ||
304 | `sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26', | ||
305 | `sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30', | ||
306 | `sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30', | ||
307 | `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.317', | ||
308 | `ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
309 | `ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
310 | `ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
311 | `ambient_i` float(3,2) unsigned NOT NULL DEFAULT '0.35', | ||
312 | `east_angle` float(3,2) unsigned NOT NULL DEFAULT '0.00', | ||
313 | `sun_glow_focus` float(3,2) unsigned NOT NULL DEFAULT '0.10', | ||
314 | `sun_glow_size` float(3,2) unsigned NOT NULL DEFAULT '1.75', | ||
315 | `scene_gamma` float(4,2) unsigned NOT NULL DEFAULT '1.00', | ||
316 | `star_brightness` float(3,2) unsigned NOT NULL DEFAULT '0.00', | ||
317 | `cloud_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
318 | `cloud_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
319 | `cloud_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
320 | `cloud_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.41', | ||
321 | `cloud_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', | ||
322 | `cloud_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', | ||
323 | `cloud_density` float(3,2) unsigned NOT NULL DEFAULT '1.00', | ||
324 | `cloud_coverage` float(3,2) unsigned NOT NULL DEFAULT '0.27', | ||
325 | `cloud_scale` float(3,2) unsigned NOT NULL DEFAULT '0.42', | ||
326 | `cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', | ||
327 | `cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', | ||
328 | `cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12', | ||
329 | `cloud_scroll_x` float(4,2) NOT NULL DEFAULT '0.20', | ||
330 | `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', | ||
331 | `cloud_scroll_y` float(4,2) NOT NULL DEFAULT '0.01', | ||
332 | `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', | ||
333 | `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '1', | ||
334 | PRIMARY KEY (`region_id`) | ||
335 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
336 | |||
337 | CREATE TABLE IF NOT EXISTS `spawn_points` ( | ||
338 | `RegionID` varchar(36) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, | ||
339 | `Yaw` float NOT NULL, | ||
340 | `Pitch` float NOT NULL, | ||
341 | `Distance` float NOT NULL, | ||
342 | KEY `RegionID` (`RegionID`) | ||
343 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
344 | |||
345 | CREATE TABLE IF NOT EXISTS `regionenvironment` ( | ||
346 | `region_id` varchar(36) NOT NULL, | ||
347 | `llsd_settings` text NOT NULL, | ||
348 | PRIMARY KEY (`region_id`) | ||
349 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
350 | |||
351 | CREATE TABLE IF NOT EXISTS `regionextra` ( | ||
352 | `RegionID` char(36) NOT NULL, | ||
353 | `Name` varchar(32) NOT NULL, | ||
354 | `value` text, | ||
355 | PRIMARY KEY (`RegionID`,`Name`) | ||
356 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
357 | |||
358 | COMMIT; | ||
359 | |||
360 | :VERSION 52 #---- avination fields | ||
361 | |||
362 | BEGIN; | ||
363 | |||
364 | ALTER TABLE `prims` ADD COLUMN `PassCollisions` tinyint(4) NOT NULL default '0'; | ||
365 | ALTER TABLE `prims` ADD COLUMN `Vehicle` TEXT default NULL; | ||
366 | ALTER TABLE `regionsettings` ADD COLUMN `block_search` tinyint(4) NOT NULL default '0'; | ||
367 | ALTER TABLE `regionsettings` ADD COLUMN `casino` tinyint(4) NOT NULL default '0'; | ||
368 | ALTER TABLE `land` ADD COLUMN `SeeAVs` tinyint(4) NOT NULL default '1'; | ||
369 | ALTER TABLE `land` ADD COLUMN `AnyAVSounds` tinyint(4) NOT NULL default '1'; | ||
370 | ALTER TABLE `land` ADD COLUMN `GroupAVSounds` tinyint(4) NOT NULL default '1'; | ||
371 | |||
372 | COMMIT; | ||
373 | |||
374 | :VERSION 53 #---- STATUS ROTATION axis locks | ||
375 | |||
376 | BEGIN; | ||
377 | |||
378 | ALTER TABLE `prims` ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0'; | ||
379 | |||
380 | COMMIT; | ||
381 | |||
382 | :VERSION 54 #----- add baked terrain store | ||
383 | |||
384 | BEGIN; | ||
385 | |||
386 | CREATE TABLE IF NOT EXISTS `bakedterrain` ( | ||
387 | `RegionUUID` varchar(255) DEFAULT NULL, | ||
388 | `Revision` int(11) DEFAULT NULL, | ||
389 | `Heightfield` longblob | ||
390 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
391 | |||
392 | COMMIT; | ||
393 | |||
394 | :VERSION 55 #----- Increase float precision for windlight needed by scripts | ||
395 | |||
396 | BEGIN; | ||
397 | |||
398 | ALTER TABLE `regionwindlight` | ||
399 | |||
400 | MODIFY `water_fog_density_exponent` float(9,7) unsigned NOT NULL DEFAULT '4.0', | ||
401 | MODIFY `underwater_fog_modifier` float(9,8) unsigned NOT NULL DEFAULT '0.25', | ||
402 | MODIFY `reflection_wavelet_scale_1` float(9,7) unsigned NOT NULL DEFAULT '2.0', | ||
403 | MODIFY `reflection_wavelet_scale_2` float(9,7) unsigned NOT NULL DEFAULT '2.0', | ||
404 | MODIFY `reflection_wavelet_scale_3` float(9,7) unsigned NOT NULL DEFAULT '2.0', | ||
405 | MODIFY `fresnel_scale` float(9,8) unsigned NOT NULL DEFAULT '0.40', | ||
406 | MODIFY `fresnel_offset` float(9,8) unsigned NOT NULL DEFAULT '0.50', | ||
407 | MODIFY `refract_scale_above` float(9,8) unsigned NOT NULL DEFAULT '0.03', | ||
408 | MODIFY `refract_scale_below` float(9,8) unsigned NOT NULL DEFAULT '0.20', | ||
409 | MODIFY `blur_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.040', | ||
410 | MODIFY `big_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.05', | ||
411 | MODIFY `big_wave_direction_y` float(9,8) NOT NULL DEFAULT '-0.42', | ||
412 | MODIFY `little_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.11', | ||
413 | MODIFY `little_wave_direction_y` float(9,8) NOT NULL DEFAULT '-1.16', | ||
414 | MODIFY `horizon_r` float(9,8) unsigned NOT NULL DEFAULT '0.25', | ||
415 | MODIFY `horizon_g` float(9,8) unsigned NOT NULL DEFAULT '0.25', | ||
416 | MODIFY `horizon_b` float(9,8) unsigned NOT NULL DEFAULT '0.32', | ||
417 | MODIFY `horizon_i` float(9,8) unsigned NOT NULL DEFAULT '0.32', | ||
418 | MODIFY `haze_horizon` float(9,8) unsigned NOT NULL DEFAULT '0.19', | ||
419 | MODIFY `blue_density_r` float(9,8) unsigned NOT NULL DEFAULT '0.12', | ||
420 | MODIFY `blue_density_g` float(9,8) unsigned NOT NULL DEFAULT '0.22', | ||
421 | MODIFY `blue_density_b` float(9,8) unsigned NOT NULL DEFAULT '0.38', | ||
422 | MODIFY `blue_density_i` float(9,8) unsigned NOT NULL DEFAULT '0.38', | ||
423 | MODIFY `haze_density` float(9,8) unsigned NOT NULL DEFAULT '0.70', | ||
424 | MODIFY `density_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.18', | ||
425 | MODIFY `distance_multiplier` float(9,6) unsigned NOT NULL DEFAULT '0.8', | ||
426 | MODIFY `sun_moon_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.24', | ||
427 | MODIFY `sun_moon_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.26', | ||
428 | MODIFY `sun_moon_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.30', | ||
429 | MODIFY `sun_moon_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.30', | ||
430 | MODIFY `sun_moon_position` float(9,8) unsigned NOT NULL DEFAULT '0.317', | ||
431 | MODIFY `ambient_r` float(9,8) unsigned NOT NULL DEFAULT '0.35', | ||
432 | MODIFY `ambient_g` float(9,8) unsigned NOT NULL DEFAULT '0.35', | ||
433 | MODIFY `ambient_b` float(9,8) unsigned NOT NULL DEFAULT '0.35', | ||
434 | MODIFY `ambient_i` float(9,8) unsigned NOT NULL DEFAULT '0.35', | ||
435 | MODIFY `east_angle` float(9,8) unsigned NOT NULL DEFAULT '0.00', | ||
436 | MODIFY `sun_glow_focus` float(9,8) unsigned NOT NULL DEFAULT '0.10', | ||
437 | MODIFY `sun_glow_size` float(9,8) unsigned NOT NULL DEFAULT '1.75', | ||
438 | MODIFY `scene_gamma` float(9,7) unsigned NOT NULL DEFAULT '1.00', | ||
439 | MODIFY `star_brightness` float(9,8) unsigned NOT NULL DEFAULT '0.00', | ||
440 | MODIFY `cloud_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.41', | ||
441 | MODIFY `cloud_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.41', | ||
442 | MODIFY `cloud_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.41', | ||
443 | MODIFY `cloud_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.41', | ||
444 | MODIFY `cloud_x` float(9,8) unsigned NOT NULL DEFAULT '1.00', | ||
445 | MODIFY `cloud_y` float(9,8) unsigned NOT NULL DEFAULT '0.53', | ||
446 | MODIFY `cloud_density` float(9,8) unsigned NOT NULL DEFAULT '1.00', | ||
447 | MODIFY `cloud_coverage` float(9,8) unsigned NOT NULL DEFAULT '0.27', | ||
448 | MODIFY `cloud_scale` float(9,8) unsigned NOT NULL DEFAULT '0.42', | ||
449 | MODIFY `cloud_detail_x` float(9,8) unsigned NOT NULL DEFAULT '1.00', | ||
450 | MODIFY `cloud_detail_y` float(9,8) unsigned NOT NULL DEFAULT '0.53', | ||
451 | MODIFY `cloud_detail_density` float(9,8) unsigned NOT NULL DEFAULT '0.12', | ||
452 | MODIFY `cloud_scroll_x` float(9,7) NOT NULL DEFAULT '0.20', | ||
453 | MODIFY `cloud_scroll_y` float(9,7) NOT NULL DEFAULT '0.01'; | ||
454 | |||
455 | COMMIT; | ||
456 | |||
457 | :VERSION 56 #----- Add RezzerID field in table prims | ||
458 | |||
459 | BEGIN; | ||
460 | |||
461 | ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; | ||
462 | |||
463 | COMMIT; | ||
464 | |||
465 | :VERSION 57 #----- Add physics inertia data | ||
466 | |||
467 | BEGIN; | ||
468 | ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; | ||
469 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/UserAccount.migrations b/OpenSim/Data/MySQL/Resources/UserAccount.migrations new file mode 100644 index 0000000..dcb375e --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/UserAccount.migrations | |||
@@ -0,0 +1,31 @@ | |||
1 | :VERSION 5 # ------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `UserAccounts` ( | ||
6 | `PrincipalID` char(36) NOT NULL, | ||
7 | `ScopeID` char(36) NOT NULL, | ||
8 | `FirstName` varchar(64) NOT NULL, | ||
9 | `LastName` varchar(64) NOT NULL, | ||
10 | `Email` varchar(64) DEFAULT NULL, | ||
11 | `ServiceURLs` text, | ||
12 | `Created` int(11) DEFAULT NULL, | ||
13 | `UserLevel` int(11) NOT NULL DEFAULT '0', | ||
14 | `UserFlags` int(11) NOT NULL DEFAULT '0', | ||
15 | `UserTitle` varchar(64) NOT NULL DEFAULT '', | ||
16 | UNIQUE KEY `PrincipalID` (`PrincipalID`), | ||
17 | KEY `Email` (`Email`), | ||
18 | KEY `FirstName` (`FirstName`), | ||
19 | KEY `LastName` (`LastName`), | ||
20 | KEY `Name` (`FirstName`,`LastName`) | ||
21 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
22 | |||
23 | COMMIT; | ||
24 | |||
25 | :VERSION 6 # ------------------------- | ||
26 | |||
27 | BEGIN; | ||
28 | |||
29 | ALTER TABLE `UserAccounts` ADD `active` INT NOT NULL DEFAULT '1'; | ||
30 | |||
31 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/UserProfiles.migrations b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations new file mode 100644 index 0000000..512b6ed --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations | |||
@@ -0,0 +1,86 @@ | |||
1 | :VERSION 5 # ------------------------------- | ||
2 | |||
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=MyISAM 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 | `gatekeeper` varchar(255), | ||
48 | PRIMARY KEY (`pickuuid`) | ||
49 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
50 | |||
51 | |||
52 | CREATE TABLE IF NOT EXISTS `userprofile` ( | ||
53 | `useruuid` varchar(36) NOT NULL, | ||
54 | `profilePartner` varchar(36) NOT NULL, | ||
55 | `profileAllowPublish` binary(1) NOT NULL, | ||
56 | `profileMaturePublish` binary(1) NOT NULL, | ||
57 | `profileURL` varchar(255) NOT NULL, | ||
58 | `profileWantToMask` int(3) NOT NULL, | ||
59 | `profileWantToText` text NOT NULL, | ||
60 | `profileSkillsMask` int(3) NOT NULL, | ||
61 | `profileSkillsText` text NOT NULL, | ||
62 | `profileLanguages` text NOT NULL, | ||
63 | `profileImage` varchar(36) NOT NULL, | ||
64 | `profileAboutText` text NOT NULL, | ||
65 | `profileFirstImage` varchar(36) NOT NULL, | ||
66 | `profileFirstText` text NOT NULL, | ||
67 | PRIMARY KEY (`useruuid`) | ||
68 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
69 | |||
70 | CREATE TABLE IF NOT EXISTS `userdata` ( | ||
71 | `UserId` char(36) NOT NULL, | ||
72 | `TagId` varchar(64) NOT NULL, | ||
73 | `DataKey` varchar(255), | ||
74 | `DataVal` varchar(255), | ||
75 | PRIMARY KEY (`UserId`,`TagId`) | ||
76 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
77 | |||
78 | CREATE TABLE IF NOT EXISTS `usersettings` ( | ||
79 | `useruuid` varchar(36) NOT NULL, | ||
80 | `imviaemail` enum('true','false') NOT NULL, | ||
81 | `visible` enum('true','false') NOT NULL, | ||
82 | `email` varchar(254) NOT NULL, | ||
83 | PRIMARY KEY (`useruuid`) | ||
84 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; | ||
85 | |||
86 | commit; | ||
diff --git a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations new file mode 100644 index 0000000..7641a97 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations | |||
@@ -0,0 +1,32 @@ | |||
1 | # ----------------- | ||
2 | :VERSION 1 | ||
3 | |||
4 | BEGIN; | ||
5 | |||
6 | CREATE TABLE IF NOT EXISTS `XAssetsMeta` ( | ||
7 | `ID` char(36) NOT NULL, | ||
8 | `Hash` binary(32) NOT NULL, | ||
9 | `Name` varchar(64) NOT NULL, | ||
10 | `Description` varchar(64) NOT NULL, | ||
11 | `AssetType` tinyint(4) NOT NULL, | ||
12 | `Local` tinyint(1) NOT NULL, | ||
13 | `Temporary` tinyint(1) NOT NULL, | ||
14 | `CreateTime` int(11) NOT NULL, | ||
15 | `AccessTime` int(11) NOT NULL, | ||
16 | `AssetFlags` int(11) NOT NULL, | ||
17 | `CreatorID` varchar(128) NOT NULL, | ||
18 | PRIMARY KEY (`id`) | ||
19 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Version 1'; | ||
20 | |||
21 | CREATE TABLE IF NOT EXISTS `XAssetsData` ( | ||
22 | `Hash` binary(32) NOT NULL, | ||
23 | `Data` longblob NOT NULL, | ||
24 | PRIMARY KEY (`hash`) | ||
25 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Version 1'; | ||
26 | |||
27 | COMMIT; | ||
28 | |||
29 | :VERSION 2 | ||
30 | |||
31 | BEGIN; | ||
32 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/XMute.migrations b/OpenSim/Data/MySQL/Resources/XMute.migrations new file mode 100644 index 0000000..084c67b --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/XMute.migrations | |||
@@ -0,0 +1,16 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS `XMute` ( | ||
6 | `AgentID` char(36) NOT NULL, | ||
7 | `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
8 | `MuteName` varchar(64) NOT NULL DEFAULT '', | ||
9 | `MuteType` int(11) NOT NULL DEFAULT '1', | ||
10 | `MuteFlags` int(11) NOT NULL DEFAULT '0', | ||
11 | `Stamp` int(11) NOT NULL, | ||
12 | UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`), | ||
13 | KEY `AgentID` (`AgentID`) | ||
14 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
15 | |||
16 | 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..0b605ab --- /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 IF NOT EXISTS `os_groups_groups` ( | ||
6 | `GroupID` char(36) NOT NULL default '', | ||
7 | `Location` varchar(255) NOT NULL default '', | ||
8 | `Name` varchar(255) NOT NULL default '', | ||
9 | `Charter` text NOT NULL, | ||
10 | `InsigniaID` char(36) NOT NULL default '', | ||
11 | `FounderID` char(36) NOT NULL default '', | ||
12 | `MembershipFee` int(11) NOT NULL default '0', | ||
13 | `OpenEnrollment` varchar(255) NOT NULL default '', | ||
14 | `ShowInList` int(4) NOT NULL default '0', | ||
15 | `AllowPublish` int(4) NOT NULL default '0', | ||
16 | `MaturePublish` int(4) NOT NULL default '0', | ||
17 | `OwnerRoleID` char(36) NOT NULL default '', | ||
18 | PRIMARY KEY (`GroupID`), | ||
19 | UNIQUE KEY `Name` (`Name`), | ||
20 | FULLTEXT KEY `Name_2` (`Name`) | ||
21 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
22 | |||
23 | |||
24 | CREATE TABLE IF NOT EXISTS `os_groups_membership` ( | ||
25 | `GroupID`char(36) NOT NULL default '', | ||
26 | `PrincipalID` VARCHAR(255) NOT NULL default '', | ||
27 | `SelectedRoleID` char(36) NOT NULL default '', | ||
28 | `Contribution` int(11) NOT NULL default '0', | ||
29 | `ListInProfile` int(4) NOT NULL default '1', | ||
30 | `AcceptNotices` int(4) NOT NULL default '1', | ||
31 | `AccessToken` char(36) NOT NULL default '', | ||
32 | PRIMARY KEY (`GroupID`,`PrincipalID`), | ||
33 | KEY `PrincipalID` (`PrincipalID`) | ||
34 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
35 | |||
36 | |||
37 | CREATE TABLE IF NOT EXISTS `os_groups_roles` ( | ||
38 | `GroupID` char(36) NOT NULL default '', | ||
39 | `RoleID` char(36) NOT NULL default '', | ||
40 | `Name` varchar(255) NOT NULL default '', | ||
41 | `Description` varchar(255) NOT NULL default '', | ||
42 | `Title` varchar(255) NOT NULL default '', | ||
43 | `Powers` bigint(20) unsigned NOT NULL default '0', | ||
44 | PRIMARY KEY (`GroupID`,`RoleID`), | ||
45 | KEY `GroupID` (`GroupID`) | ||
46 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
47 | |||
48 | |||
49 | CREATE TABLE IF NOT EXISTS `os_groups_rolemembership` ( | ||
50 | `GroupID` char(36) NOT NULL default '', | ||
51 | `RoleID` char(36) NOT NULL default '', | ||
52 | `PrincipalID` VARCHAR(255) NOT NULL default '', | ||
53 | PRIMARY KEY (`GroupID`,`RoleID`,`PrincipalID`), | ||
54 | KEY `PrincipalID` (`PrincipalID`) | ||
55 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
56 | |||
57 | |||
58 | CREATE TABLE IF NOT EXISTS `os_groups_invites` ( | ||
59 | `InviteID` char(36) NOT NULL default '', | ||
60 | `GroupID` char(36) NOT NULL default '', | ||
61 | `RoleID` char(36) NOT NULL default '', | ||
62 | `PrincipalID` VARCHAR(255) NOT NULL default '', | ||
63 | `TMStamp` timestamp NOT NULL, | ||
64 | PRIMARY KEY (`InviteID`), | ||
65 | UNIQUE KEY `PrincipalGroup` (`GroupID`,`PrincipalID`) | ||
66 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
67 | |||
68 | |||
69 | CREATE TABLE IF NOT EXISTS `os_groups_notices` ( | ||
70 | `GroupID` char(36) NOT NULL default '', | ||
71 | `NoticeID` char(36) NOT NULL default '', | ||
72 | `TMStamp` int(10) unsigned NOT NULL default '0', | ||
73 | `FromName` varchar(255) NOT NULL default '', | ||
74 | `Subject` varchar(255) NOT NULL default '', | ||
75 | `Message` text NOT NULL, | ||
76 | `HasAttachment` int(4) NOT NULL default '0', | ||
77 | `AttachmentType` int(4) NOT NULL default '0', | ||
78 | `AttachmentName` varchar(128) NOT NULL default '', | ||
79 | `AttachmentItemID` char(36) NOT NULL default '', | ||
80 | `AttachmentOwnerID` varchar(255) NOT NULL default '', | ||
81 | PRIMARY KEY (`NoticeID`), | ||
82 | KEY `GroupID` (`GroupID`), | ||
83 | KEY `TMStamp` (`TMStamp`) | ||
84 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
85 | |||
86 | CREATE TABLE IF NOT EXISTS `os_groups_principals` ( | ||
87 | `PrincipalID` VARCHAR(255) NOT NULL default '', | ||
88 | `ActiveGroupID` char(36) NOT NULL default '', | ||
89 | PRIMARY KEY (`PrincipalID`) | ||
90 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
91 | |||
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; | ||