aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MSSQL/MSSQLEstateData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/MSSQL/MSSQLEstateData.cs')
-rw-r--r--OpenSim/Data/MSSQL/MSSQLEstateData.cs434
1 files changed, 434 insertions, 0 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
new file mode 100644
index 0000000..ca4691c
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
@@ -0,0 +1,434 @@
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 OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Data.SqlClient;
32using System.Reflection;
33using libsecondlife;
34using log4net;
35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces;
37
38namespace OpenSim.Data.MSSQL
39{
40 public class MSSQLEstateData : IEstateDataStore
41 {
42 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 private MSSQLManager _Database;
45
46 private FieldInfo[] _Fields;
47 private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>();
48
49 #region Public methods
50
51 /// <summary>
52 /// Initialises the estatedata class.
53 /// </summary>
54 /// <param name="connectionString">connectionString.</param>
55 public void Initialise(string connectionString)
56 {
57 if (string.IsNullOrEmpty(connectionString))
58 {
59 _Database = new MSSQLManager(connectionString);
60 }
61 else
62 {
63 //TODO when can this be deleted
64 IniFile iniFile = new IniFile("mssql_connection.ini");
65 string settingDataSource = iniFile.ParseFileReadValue("data_source");
66 string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog");
67 string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info");
68 string settingUserId = iniFile.ParseFileReadValue("user_id");
69 string settingPassword = iniFile.ParseFileReadValue("password");
70
71 _Database =
72 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
73 settingPassword);
74 }
75
76 //Migration settings
77 using (SqlConnection connection = _Database.DatabaseConnection())
78 {
79 Assembly assem = GetType().Assembly;
80 MSSQLMigration migration = new MSSQLMigration(connection, assem, "EstateStore");
81
82 migration.Update();
83
84 connection.Close();
85 }
86
87 //Interesting way to get parameters! Maybe implement that also with other types
88 Type t = typeof(EstateSettings);
89 _Fields = t.GetFields(BindingFlags.NonPublic |
90 BindingFlags.Instance |
91 BindingFlags.DeclaredOnly);
92
93 foreach (FieldInfo f in _Fields)
94 {
95 if (f.Name.Substring(0, 2) == "m_")
96 _FieldMap[f.Name.Substring(2)] = f;
97 }
98 }
99
100 /// <summary>
101 /// Loads the estate settings.
102 /// </summary>
103 /// <param name="regionID">region ID.</param>
104 /// <returns></returns>
105 public EstateSettings LoadEstateSettings(LLUUID regionID)
106 {
107 EstateSettings es = new EstateSettings();
108
109 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = @RegionID";
110
111 bool insertEstate = false;
112
113 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
114 {
115 cmd.Parameters.AddWithValue("@RegionID", regionID.ToString());
116
117 using (IDataReader reader = cmd.ExecuteReader())
118 {
119 if (reader.Read())
120 {
121 foreach (string name in FieldList)
122 {
123 if (_FieldMap[name].GetValue(es) is bool)
124 {
125 int v = Convert.ToInt32(reader[name]);
126 if (v != 0)
127 _FieldMap[name].SetValue(es, true);
128 else
129 _FieldMap[name].SetValue(es, false);
130 }
131 else if (_FieldMap[name].GetValue(es) is LLUUID)
132 {
133 LLUUID uuid;
134 LLUUID.TryParse(reader[name].ToString(), out uuid);
135
136 _FieldMap[name].SetValue(es, uuid);
137 }
138 else
139 {
140 _FieldMap[name].SetValue(es, reader[name]);
141 }
142 }
143 }
144 else
145 {
146 insertEstate = true;
147 }
148 }
149 }
150
151
152 if (insertEstate)
153 {
154 List<string> names = new List<string>(FieldList);
155
156 names.Remove("EstateID");
157
158 sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
159
160 //_Log.Debug("[DB ESTATE]: SQL: " + sql);
161 using (SqlConnection connection = _Database.DatabaseConnection())
162 {
163 using (SqlCommand insertCommand = connection.CreateCommand())
164 {
165 insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
166
167 foreach (string name in names)
168 {
169 if (_FieldMap[name].GetValue(es) is bool)
170 {
171 SqlParameter tempBool = new SqlParameter("@" + name, SqlDbType.Bit);
172
173 if ((bool) _FieldMap[name].GetValue(es))
174 tempBool.Value = 1;
175 else
176 tempBool.Value = 0;
177
178 insertCommand.Parameters.Add(tempBool);
179 }
180 else
181 {
182 //cmd.Parameters.AddWithValue("@" + name, _FieldMap[name].GetValue(es));
183 SqlParameter tempPar = new SqlParameter("@" + name,
184 _Database.DbtypeFromType(_FieldMap[name].FieldType));
185 tempPar.Value = _FieldMap[name].GetValue(es).ToString();
186
187 insertCommand.Parameters.Add(tempPar);
188 }
189 }
190
191
192 SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
193 idParameter.Direction = ParameterDirection.Output;
194 insertCommand.Parameters.Add(idParameter);
195
196 insertCommand.ExecuteNonQuery();
197
198 es.EstateID = Convert.ToUInt32(idParameter.Value);
199 }
200 }
201
202 using (AutoClosingSqlCommand cmd = _Database.Query("insert into estate_map values (@RegionID, @EstateID)"))
203 {
204 cmd.Parameters.AddWithValue("@RegionID", regionID.ToString());
205 cmd.Parameters.AddWithValue("@EstateID", es.EstateID);
206 // This will throw on dupe key
207 try
208 {
209 cmd.ExecuteNonQuery();
210 }
211 catch (Exception)
212 {
213 _Log.Debug("[ESTATE DB]: Error inserting regionID and EstateID in estate_map");
214 }
215 }
216
217 // Munge and transfer the ban list
218 //
219
220 sql = string.Format("insert into estateban select {0}, bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = @UUID", es.EstateID);
221 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
222 {
223 cmd.Parameters.AddWithValue("@UUID", regionID);
224 try
225 {
226
227 cmd.ExecuteNonQuery();
228 }
229 catch (Exception)
230 {
231 _Log.Debug("[ESTATE DB]: Error setting up estateban from regionban");
232 }
233 }
234
235 //TODO check if this is needed??
236 es.Save();
237 }
238
239 LoadBanList(es);
240
241 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
242 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
243 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
244
245 //Set event
246 es.OnSave += StoreEstateSettings;
247 return es;
248 }
249
250 /// <summary>
251 /// Stores the estate settings.
252 /// </summary>
253 /// <param name="es">estate settings</param>
254 public void StoreEstateSettings(EstateSettings es)
255 {
256 List<string> names = new List<string>(FieldList);
257
258 names.Remove("EstateID");
259
260 string sql = string.Format("UPDATE estate_settings SET ") ; // ({0}) values ( @{1}) WHERE EstateID = @EstateID", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
261 foreach (string name in names)
262 {
263 sql += name + " = @" + name + ", ";
264 }
265 sql = sql.Remove(sql.LastIndexOf(","));
266 sql += " WHERE EstateID = @EstateID";
267
268 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
269 {
270 foreach (string name in names)
271 {
272 if (_FieldMap[name].GetValue(es) is bool)
273 {
274 SqlParameter tempBool = new SqlParameter("@" + name, SqlDbType.Bit);
275
276 if ((bool)_FieldMap[name].GetValue(es))
277 tempBool.Value = 1;
278 else
279 tempBool.Value = 0;
280
281 cmd.Parameters.Add(tempBool);
282 }
283 else
284 {
285 //cmd.Parameters.AddWithValue("@" + name, _FieldMap[name].GetValue(es));
286 SqlParameter tempPar = new SqlParameter("@" + name,
287 _Database.DbtypeFromType(_FieldMap[name].FieldType));
288 tempPar.Value = _FieldMap[name].GetValue(es).ToString();
289
290 cmd.Parameters.Add(tempPar);
291 }
292 }
293
294
295 SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int);
296 idParameter.Value = es.EstateID;
297 cmd.Parameters.Add(idParameter);
298
299 cmd.ExecuteNonQuery();
300 }
301
302 SaveBanList(es);
303 SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
304 SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
305 SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
306 }
307
308 #endregion
309
310 #region Private methods
311
312 private string[] FieldList
313 {
314 get { return new List<string>(_FieldMap.Keys).ToArray(); }
315 }
316
317 private void LoadBanList(EstateSettings es)
318 {
319 es.ClearBans();
320
321 string sql = "select bannedUUID from estateban where EstateID = @EstateID";
322
323 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
324 {
325 SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int);
326 idParameter.Value = es.EstateID;
327 cmd.Parameters.Add(idParameter);
328
329 using (IDataReader reader = cmd.ExecuteReader())
330 {
331 while (reader.Read())
332 {
333 EstateBan eb = new EstateBan();
334
335 LLUUID uuid;
336 LLUUID.TryParse(reader["bannedUUID"].ToString(), out uuid);
337
338 eb.bannedUUID = uuid;
339 eb.bannedIP = "0.0.0.0";
340 eb.bannedIPHostMask = "0.0.0.0";
341 es.AddBan(eb);
342 }
343 }
344 }
345 }
346
347 private LLUUID[] LoadUUIDList(uint estateID, string table)
348 {
349 List<LLUUID> uuids = new List<LLUUID>();
350
351 string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table);
352
353 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
354 {
355 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
356
357 using (IDataReader reader = cmd.ExecuteReader())
358 {
359 while (reader.Read())
360 {
361 // EstateBan eb = new EstateBan();
362
363 LLUUID uuid;
364 LLUUID.TryParse(reader["uuid"].ToString(), out uuid);
365
366 uuids.Add(uuid);
367 }
368 }
369 }
370
371 return uuids.ToArray();
372 }
373
374 private void SaveBanList(EstateSettings es)
375 {
376 //Delete first
377 string sql = "delete from estateban where EstateID = @EstateID";
378 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
379 {
380 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
381 cmd.ExecuteNonQuery();
382 }
383
384 //Insert after
385 sql = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )";
386 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
387 {
388 foreach (EstateBan b in es.EstateBans)
389 {
390 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
391
392 cmd.Parameters.Add(_Database.CreateParameter("@bannedUUID", b.bannedUUID));
393
394 cmd.ExecuteNonQuery();
395
396 cmd.Parameters.Clear();
397 }
398 }
399 }
400
401 private void SaveUUIDList(uint estateID, string table, LLUUID[] data)
402 {
403 //Delete first
404 string sql = string.Format("delete from {0} where EstateID = @EstateID", table);
405 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
406 {
407 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
408 cmd.ExecuteNonQuery();
409 }
410
411 sql = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table);
412 using (AutoClosingSqlCommand cmd = _Database.Query(sql))
413 {
414 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
415
416 bool createParamOnce = true;
417
418 foreach (LLUUID uuid in data)
419 {
420 if (createParamOnce)
421 {
422 cmd.Parameters.Add(_Database.CreateParameter("@uuid", uuid));
423 createParamOnce = false;
424 }
425 else
426 cmd.Parameters["@uuid"].Value = uuid.ToString();
427
428 cmd.ExecuteNonQuery();
429 }
430 }
431 }
432 #endregion
433 }
434}