OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
MySQLEstateData.cs
Go to the documentation of this file.
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 {
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 
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 
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 
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 }
MySQLEstateStore(string connectionString)
List< int > GetEstatesByOwner(UUID ownerID)
Get the IDs of all estates owned by the given user.
List< int > GetEstatesAll()
Get the IDs of all estates.
EstateSettings CreateNewEstate()
Create a new estate.
EstateSettings LoadEstateSettings(int estateID)
Load estate settings for an estate ID.
List< EstateSettings > LoadEstateSettingsAll()
Load/Get all estate settings.
bool LinkRegion(UUID regionID, int estateID)
Link a region to an estate.
List< UUID > GetRegions(int estateID)
Get the UUIDs of all the regions in an estate.
void StoreEstateSettings(EstateSettings es)
Store estate settings.
void Initialise(string connectionString)
Initialise the data store.
EstateSettings LoadEstateSettings(UUID regionID, bool create)
Load estate settings for a region.
List< int > GetEstates(string search)
Get estate IDs.
bool DeleteEstate(int estateID)
Delete an estate