aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MySQL/MySQLRegionData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/MySQL/MySQLRegionData.cs')
-rw-r--r--OpenSim/Data/MySQL/MySQLRegionData.cs421
1 files changed, 421 insertions, 0 deletions
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Data;
32using System.Reflection;
33using MySql.Data.MySqlClient;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Data;
37using RegionFlags = OpenSim.Framework.RegionFlags;
38
39namespace 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