aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MySQL/MySQLEstateData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/MySQL/MySQLEstateData.cs')
-rw-r--r--OpenSim/Data/MySQL/MySQLEstateData.cs594
1 files changed, 594 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs
new file mode 100644
index 0000000..fe1487b
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLEstateData.cs
@@ -0,0 +1,594 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Reflection;
32using log4net;
33using MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Data;
38
39namespace OpenSim.Data.MySQL
40{
41 public class MySQLEstateStore : IEstateDataStore
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private string m_connectionString;
47
48 private FieldInfo[] m_Fields;
49 private Dictionary<string, FieldInfo> m_FieldMap =
50 new Dictionary<string, FieldInfo>();
51
52 protected virtual Assembly Assembly
53 {
54 get { return GetType().Assembly; }
55 }
56
57 public MySQLEstateStore()
58 {
59 }
60
61 public MySQLEstateStore(string connectionString)
62 {
63 Initialise(connectionString);
64 }
65
66 public void Initialise(string connectionString)
67 {
68 m_connectionString = connectionString;
69
70 try
71 {
72 m_log.Info("[REGION DB]: MySql - connecting: " + Util.GetDisplayConnectionString(m_connectionString));
73 }
74 catch (Exception e)
75 {
76 m_log.Debug("Exception: password not found in connection string\n" + e.ToString());
77 }
78
79 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
80 {
81 dbcon.Open();
82
83 Migration m = new Migration(dbcon, Assembly, "EstateStore");
84 m.Update();
85
86 Type t = typeof(EstateSettings);
87 m_Fields = t.GetFields(BindingFlags.NonPublic |
88 BindingFlags.Instance |
89 BindingFlags.DeclaredOnly);
90
91 foreach (FieldInfo f in m_Fields)
92 {
93 if (f.Name.Substring(0, 2) == "m_")
94 m_FieldMap[f.Name.Substring(2)] = f;
95 }
96 }
97 }
98
99 private string[] FieldList
100 {
101 get { return new List<string>(m_FieldMap.Keys).ToArray(); }
102 }
103
104 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
105 {
106 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) +
107 " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID";
108
109 using (MySqlCommand cmd = new MySqlCommand())
110 {
111 cmd.CommandText = sql;
112 cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
113
114 EstateSettings e = DoLoad(cmd, regionID, create);
115 if (!create && e.EstateID == 0) // Not found
116 return null;
117
118 return e;
119 }
120 }
121
122 public EstateSettings CreateNewEstate()
123 {
124 EstateSettings es = new EstateSettings();
125 es.OnSave += StoreEstateSettings;
126
127 DoCreate(es);
128
129 LoadBanList(es);
130
131 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
132 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
133 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
134
135 return es;
136 }
137
138 private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
139 {
140 EstateSettings es = new EstateSettings();
141 es.OnSave += StoreEstateSettings;
142
143 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
144 {
145 dbcon.Open();
146
147 cmd.Connection = dbcon;
148
149 bool found = false;
150
151 using (IDataReader r = cmd.ExecuteReader())
152 {
153 if (r.Read())
154 {
155 found = true;
156
157 foreach (string name in FieldList)
158 {
159 if (m_FieldMap[name].FieldType == typeof(bool))
160 {
161 m_FieldMap[name].SetValue(es, Convert.ToInt32(r[name]) != 0);
162 }
163 else if (m_FieldMap[name].FieldType == typeof(UUID))
164 {
165 m_FieldMap[name].SetValue(es, DBGuid.FromDB(r[name]));
166 }
167 else
168 {
169 m_FieldMap[name].SetValue(es, r[name]);
170 }
171 }
172 }
173 }
174
175 if (!found && create)
176 {
177 DoCreate(es);
178 LinkRegion(regionID, (int)es.EstateID);
179 }
180 }
181
182 LoadBanList(es);
183 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
184 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
185 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
186 return es;
187 }
188
189 private void DoCreate(EstateSettings es)
190 {
191 // Migration case
192 List<string> names = new List<string>(FieldList);
193
194 names.Remove("EstateID");
195
196 string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
197
198 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
199 {
200 dbcon.Open();
201 using (MySqlCommand cmd2 = dbcon.CreateCommand())
202 {
203 cmd2.CommandText = sql;
204 cmd2.Parameters.Clear();
205
206 foreach (string name in FieldList)
207 {
208 if (m_FieldMap[name].GetValue(es) is bool)
209 {
210 if ((bool)m_FieldMap[name].GetValue(es))
211 cmd2.Parameters.AddWithValue("?" + name, "1");
212 else
213 cmd2.Parameters.AddWithValue("?" + name, "0");
214 }
215 else
216 {
217 cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
218 }
219 }
220
221 cmd2.ExecuteNonQuery();
222
223 cmd2.CommandText = "select LAST_INSERT_ID() as id";
224 cmd2.Parameters.Clear();
225
226 using (IDataReader r = cmd2.ExecuteReader())
227 {
228 r.Read();
229 es.EstateID = Convert.ToUInt32(r["id"]);
230 }
231
232 es.Save();
233 }
234 }
235 }
236
237 public void StoreEstateSettings(EstateSettings es)
238 {
239 string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
240
241 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
242 {
243 dbcon.Open();
244
245 using (MySqlCommand cmd = dbcon.CreateCommand())
246 {
247 cmd.CommandText = sql;
248
249 foreach (string name in FieldList)
250 {
251 if (m_FieldMap[name].GetValue(es) is bool)
252 {
253 if ((bool)m_FieldMap[name].GetValue(es))
254 cmd.Parameters.AddWithValue("?" + name, "1");
255 else
256 cmd.Parameters.AddWithValue("?" + name, "0");
257 }
258 else
259 {
260 cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
261 }
262 }
263
264 cmd.ExecuteNonQuery();
265 }
266 }
267
268 SaveBanList(es);
269 SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
270 SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
271 SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
272 }
273
274 private void LoadBanList(EstateSettings es)
275 {
276 es.ClearBans();
277
278 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
279 {
280 dbcon.Open();
281
282 using (MySqlCommand cmd = dbcon.CreateCommand())
283 {
284 cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID";
285 cmd.Parameters.AddWithValue("?EstateID", es.EstateID);
286
287 using (IDataReader r = cmd.ExecuteReader())
288 {
289 while (r.Read())
290 {
291 EstateBan eb = new EstateBan();
292
293 UUID uuid = new UUID();
294 UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
295
296 eb.BannedUserID = uuid;
297 eb.BannedHostAddress = "0.0.0.0";
298 eb.BannedHostIPMask = "0.0.0.0";
299 es.AddBan(eb);
300 }
301 }
302 }
303 }
304 }
305
306 private void SaveBanList(EstateSettings es)
307 {
308 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
309 {
310 dbcon.Open();
311
312 using (MySqlCommand cmd = dbcon.CreateCommand())
313 {
314 cmd.CommandText = "delete from estateban where EstateID = ?EstateID";
315 cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
316
317 cmd.ExecuteNonQuery();
318
319 cmd.Parameters.Clear();
320
321 cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )";
322
323 foreach (EstateBan b in es.EstateBans)
324 {
325 cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
326 cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString());
327
328 cmd.ExecuteNonQuery();
329 cmd.Parameters.Clear();
330 }
331 }
332 }
333 }
334
335 void SaveUUIDList(uint EstateID, string table, UUID[] data)
336 {
337 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
338 {
339 dbcon.Open();
340
341 using (MySqlCommand cmd = dbcon.CreateCommand())
342 {
343 cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID";
344 cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString());
345
346 cmd.ExecuteNonQuery();
347
348 cmd.Parameters.Clear();
349
350 cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )";
351
352 foreach (UUID uuid in data)
353 {
354 cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString());
355 cmd.Parameters.AddWithValue("?uuid", uuid.ToString());
356
357 cmd.ExecuteNonQuery();
358 cmd.Parameters.Clear();
359 }
360 }
361 }
362 }
363
364 UUID[] LoadUUIDList(uint EstateID, string table)
365 {
366 List<UUID> uuids = new List<UUID>();
367
368 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
369 {
370 dbcon.Open();
371
372 using (MySqlCommand cmd = dbcon.CreateCommand())
373 {
374 cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID";
375 cmd.Parameters.AddWithValue("?EstateID", EstateID);
376
377 using (IDataReader r = cmd.ExecuteReader())
378 {
379 while (r.Read())
380 {
381 // EstateBan eb = new EstateBan();
382 uuids.Add(DBGuid.FromDB(r["uuid"]));
383 }
384 }
385 }
386 }
387
388 return uuids.ToArray();
389 }
390
391 public EstateSettings LoadEstateSettings(int estateID)
392 {
393 using (MySqlCommand cmd = new MySqlCommand())
394 {
395 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = ?EstateID";
396
397 cmd.CommandText = sql;
398 cmd.Parameters.AddWithValue("?EstateID", estateID);
399
400 EstateSettings e = DoLoad(cmd, UUID.Zero, false);
401 if (e.EstateID != estateID)
402 return null;
403 return e;
404 }
405 }
406
407 public List<EstateSettings> LoadEstateSettingsAll()
408 {
409 List<EstateSettings> allEstateSettings = new List<EstateSettings>();
410
411 List<int> allEstateIds = GetEstatesAll();
412
413 foreach (int estateId in allEstateIds)
414 allEstateSettings.Add(LoadEstateSettings(estateId));
415
416 return allEstateSettings;
417 }
418
419 public List<int> GetEstatesAll()
420 {
421 List<int> result = new List<int>();
422
423 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
424 {
425 dbcon.Open();
426
427 using (MySqlCommand cmd = dbcon.CreateCommand())
428 {
429 cmd.CommandText = "select estateID from estate_settings";
430
431 using (IDataReader reader = cmd.ExecuteReader())
432 {
433 while (reader.Read())
434 {
435 result.Add(Convert.ToInt32(reader["EstateID"]));
436 }
437 reader.Close();
438 }
439 }
440
441 dbcon.Close();
442 }
443
444 return result;
445 }
446
447 public List<int> GetEstates(string search)
448 {
449 List<int> result = new List<int>();
450
451 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
452 {
453 dbcon.Open();
454
455 using (MySqlCommand cmd = dbcon.CreateCommand())
456 {
457 cmd.CommandText = "select estateID from estate_settings where EstateName = ?EstateName";
458 cmd.Parameters.AddWithValue("?EstateName", search);
459
460 using (IDataReader reader = cmd.ExecuteReader())
461 {
462 while (reader.Read())
463 {
464 result.Add(Convert.ToInt32(reader["EstateID"]));
465 }
466 reader.Close();
467 }
468 }
469
470 dbcon.Close();
471 }
472
473 return result;
474 }
475
476 public List<int> GetEstatesByOwner(UUID ownerID)
477 {
478 List<int> result = new List<int>();
479
480 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
481 {
482 dbcon.Open();
483
484 using (MySqlCommand cmd = dbcon.CreateCommand())
485 {
486 cmd.CommandText = "select estateID from estate_settings where EstateOwner = ?EstateOwner";
487 cmd.Parameters.AddWithValue("?EstateOwner", ownerID);
488
489 using (IDataReader reader = cmd.ExecuteReader())
490 {
491 while (reader.Read())
492 {
493 result.Add(Convert.ToInt32(reader["EstateID"]));
494 }
495 reader.Close();
496 }
497 }
498
499 dbcon.Close();
500 }
501
502 return result;
503 }
504
505 public bool LinkRegion(UUID regionID, int estateID)
506 {
507 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
508 {
509 dbcon.Open();
510 MySqlTransaction transaction = dbcon.BeginTransaction();
511
512 try
513 {
514 // Delete any existing association of this region with an estate.
515 using (MySqlCommand cmd = dbcon.CreateCommand())
516 {
517 cmd.Transaction = transaction;
518 cmd.CommandText = "delete from estate_map where RegionID = ?RegionID";
519 cmd.Parameters.AddWithValue("?RegionID", regionID);
520
521 cmd.ExecuteNonQuery();
522 }
523
524 using (MySqlCommand cmd = dbcon.CreateCommand())
525 {
526 cmd.Transaction = transaction;
527 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
528 cmd.Parameters.AddWithValue("?RegionID", regionID);
529 cmd.Parameters.AddWithValue("?EstateID", estateID);
530
531 int ret = cmd.ExecuteNonQuery();
532
533 if (ret != 0)
534 transaction.Commit();
535 else
536 transaction.Rollback();
537
538 dbcon.Close();
539
540 return (ret != 0);
541 }
542 }
543 catch (MySqlException ex)
544 {
545 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
546 transaction.Rollback();
547 }
548
549 dbcon.Close();
550 }
551
552 return false;
553 }
554
555 public List<UUID> GetRegions(int estateID)
556 {
557 List<UUID> result = new List<UUID>();
558
559 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
560 {
561 dbcon.Open();
562
563 try
564 {
565 using (MySqlCommand cmd = dbcon.CreateCommand())
566 {
567 cmd.CommandText = "select RegionID from estate_map where EstateID = ?EstateID";
568 cmd.Parameters.AddWithValue("?EstateID", estateID.ToString());
569
570 using (IDataReader reader = cmd.ExecuteReader())
571 {
572 while(reader.Read())
573 result.Add(DBGuid.FromDB(reader["RegionID"]));
574 reader.Close();
575 }
576 }
577 }
578 catch (Exception e)
579 {
580 m_log.Error("[REGION DB]: Error reading estate map. " + e.ToString());
581 return result;
582 }
583 dbcon.Close();
584 }
585
586 return result;
587 }
588
589 public bool DeleteEstate(int estateID)
590 {
591 return false;
592 }
593 }
594}