diff options
author | Melanie Thielker | 2008-09-01 17:10:01 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-09-01 17:10:01 +0000 |
commit | b6bb5f944f19b330656105ff79cd5ca3f2d5c242 (patch) | |
tree | 433ee8a24136ac10ed63dc3cf715b16ba786b8a8 | |
parent | Mantis #2072 (diff) | |
download | opensim-SC-b6bb5f944f19b330656105ff79cd5ca3f2d5c242.zip opensim-SC-b6bb5f944f19b330656105ff79cd5ca3f2d5c242.tar.gz opensim-SC-b6bb5f944f19b330656105ff79cd5ca3f2d5c242.tar.bz2 opensim-SC-b6bb5f944f19b330656105ff79cd5ca3f2d5c242.tar.xz |
Mantis #2095
Thank you, RuudL, for a complete adaptation of migration and estate
data to MSSQL, and the updating of the RegionData handling in MSSQL.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Data/MSSQL/MSSQLEstateData.cs | 434 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/MSSQLManager.cs | 116 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/MSSQLMigration.cs | 45 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/MSSQLRegionData.cs | 2410 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/Resources/001_EstateStore.sql | 85 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/Resources/002_RegionStore.sql | 50 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/Resources/003_RegionStore.sql | 67 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/Resources/004_RegionStore.sql | 40 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/Resources/005_RegionStore.sql | 49 | ||||
-rw-r--r-- | OpenSim/Data/MSSQL/Resources/006_RegionStore.sql | 36 | ||||
-rw-r--r-- | OpenSim/Data/Migration.cs | 10 |
11 files changed, 1971 insertions, 1371 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Data.SqlClient; | ||
32 | using System.Reflection; | ||
33 | using libsecondlife; | ||
34 | using log4net; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Region.Environment.Interfaces; | ||
37 | |||
38 | namespace 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 | } | ||
diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs index 1a053d5..535cf33 100644 --- a/OpenSim/Data/MSSQL/MSSQLManager.cs +++ b/OpenSim/Data/MSSQL/MSSQLManager.cs | |||
@@ -64,9 +64,20 @@ namespace OpenSim.Data.MSSQL | |||
64 | connectionString = builder.ToString(); | 64 | connectionString = builder.ToString(); |
65 | } | 65 | } |
66 | 66 | ||
67 | private SqlConnection createConnection() | 67 | /// <summary> |
68 | /// Initialize the manager and set the connectionstring | ||
69 | /// </summary> | ||
70 | /// <param name="connection"></param> | ||
71 | public MSSQLManager(string connection) | ||
72 | { | ||
73 | connectionString = connection; | ||
74 | } | ||
75 | |||
76 | public SqlConnection DatabaseConnection() | ||
68 | { | 77 | { |
69 | SqlConnection conn = new SqlConnection(connectionString); | 78 | SqlConnection conn = new SqlConnection(connectionString); |
79 | |||
80 | //TODO is this good??? Opening connection here | ||
70 | conn.Open(); | 81 | conn.Open(); |
71 | 82 | ||
72 | return conn; | 83 | return conn; |
@@ -186,6 +197,105 @@ namespace OpenSim.Data.MSSQL | |||
186 | } | 197 | } |
187 | } | 198 | } |
188 | 199 | ||
200 | /// <summary> | ||
201 | /// Type conversion to a SQLDbType functions | ||
202 | /// </summary> | ||
203 | /// <param name="type"></param> | ||
204 | /// <returns></returns> | ||
205 | internal SqlDbType DbtypeFromType(Type type) | ||
206 | { | ||
207 | if (type == typeof(string)) | ||
208 | { | ||
209 | return SqlDbType.VarChar; | ||
210 | } | ||
211 | if (type == typeof(double)) | ||
212 | { | ||
213 | return SqlDbType.Float; | ||
214 | } | ||
215 | if (type == typeof(int)) | ||
216 | { | ||
217 | return SqlDbType.Int; | ||
218 | } | ||
219 | if (type == typeof(bool)) | ||
220 | { | ||
221 | return SqlDbType.Bit; | ||
222 | } | ||
223 | if (type == typeof(LLUUID)) | ||
224 | { | ||
225 | return SqlDbType.VarChar; | ||
226 | } | ||
227 | if (type == typeof(Byte[])) | ||
228 | { | ||
229 | return SqlDbType.Image; | ||
230 | } | ||
231 | if (type == typeof(uint)) | ||
232 | { | ||
233 | return SqlDbType.Int; | ||
234 | } | ||
235 | return SqlDbType.VarChar; | ||
236 | } | ||
237 | |||
238 | /// <summary> | ||
239 | /// Creates value for parameter. | ||
240 | /// </summary> | ||
241 | /// <param name="value">The value.</param> | ||
242 | /// <returns></returns> | ||
243 | private static object CreateParameterValue(object value) | ||
244 | { | ||
245 | Type valueType = value.GetType(); | ||
246 | |||
247 | if (valueType == typeof(LLUUID)) | ||
248 | { | ||
249 | return value.ToString(); | ||
250 | } | ||
251 | if (valueType == typeof(bool)) | ||
252 | { | ||
253 | return (bool)value ? 1 : 0; | ||
254 | } | ||
255 | if (valueType == typeof(Byte[])) | ||
256 | { | ||
257 | return value; | ||
258 | } | ||
259 | return value; | ||
260 | } | ||
261 | |||
262 | /// <summary> | ||
263 | /// Create a parameter for a command | ||
264 | /// </summary> | ||
265 | /// <param name="parameterName">Name of the parameter.</param> | ||
266 | /// <param name="parameterObject">parameter object.</param> | ||
267 | /// <returns></returns> | ||
268 | internal SqlParameter CreateParameter(string parameterName, object parameterObject) | ||
269 | { | ||
270 | return CreateParameter(parameterName, parameterObject, false); | ||
271 | } | ||
272 | |||
273 | /// <summary> | ||
274 | /// Creates the parameter for a command. | ||
275 | /// </summary> | ||
276 | /// <param name="parameterName">Name of the parameter.</param> | ||
277 | /// <param name="parameterObject">parameter object.</param> | ||
278 | /// <param name="parameterOut">if set to <c>true</c> parameter is a output parameter</param> | ||
279 | /// <returns></returns> | ||
280 | internal SqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut) | ||
281 | { | ||
282 | //Tweak so we dont always have to add @ sign | ||
283 | if (!parameterName.StartsWith("@")) parameterName = "@" + parameterName; | ||
284 | |||
285 | SqlParameter parameter = new SqlParameter(parameterName, DbtypeFromType(parameterObject.GetType())); | ||
286 | |||
287 | if (parameterOut) | ||
288 | { | ||
289 | parameter.Direction = ParameterDirection.Output; | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | parameter.Direction = ParameterDirection.Input; | ||
294 | parameter.Value = CreateParameterValue(parameterObject); | ||
295 | } | ||
296 | |||
297 | return parameter; | ||
298 | } | ||
189 | 299 | ||
190 | private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>(); | 300 | private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>(); |
191 | internal AutoClosingSqlCommand Query(string sql) | 301 | internal AutoClosingSqlCommand Query(string sql) |
@@ -201,7 +311,7 @@ namespace OpenSim.Data.MSSQL | |||
201 | /// <returns>A Sql DB Command</returns> | 311 | /// <returns>A Sql DB Command</returns> |
202 | internal AutoClosingSqlCommand Query(string sql, Dictionary<string, string> parameters) | 312 | internal AutoClosingSqlCommand Query(string sql, Dictionary<string, string> parameters) |
203 | { | 313 | { |
204 | SqlCommand dbcommand = createConnection().CreateCommand(); | 314 | SqlCommand dbcommand = DatabaseConnection().CreateCommand(); |
205 | dbcommand.CommandText = sql; | 315 | dbcommand.CommandText = sql; |
206 | foreach (KeyValuePair<string, string> param in parameters) | 316 | foreach (KeyValuePair<string, string> param in parameters) |
207 | { | 317 | { |
@@ -211,8 +321,6 @@ namespace OpenSim.Data.MSSQL | |||
211 | return new AutoClosingSqlCommand(dbcommand); | 321 | return new AutoClosingSqlCommand(dbcommand); |
212 | } | 322 | } |
213 | 323 | ||
214 | |||
215 | |||
216 | /// <summary> | 324 | /// <summary> |
217 | /// Runs a database reader object and returns a region row | 325 | /// Runs a database reader object and returns a region row |
218 | /// </summary> | 326 | /// </summary> |
diff --git a/OpenSim/Data/MSSQL/MSSQLMigration.cs b/OpenSim/Data/MSSQL/MSSQLMigration.cs new file mode 100644 index 0000000..67fc606 --- /dev/null +++ b/OpenSim/Data/MSSQL/MSSQLMigration.cs | |||
@@ -0,0 +1,45 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Data; | ||
4 | using System.Data.Common; | ||
5 | using System.Reflection; | ||
6 | using System.Text; | ||
7 | |||
8 | namespace OpenSim.Data.MSSQL | ||
9 | { | ||
10 | public class MSSQLMigration : Migration | ||
11 | { | ||
12 | public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type) | ||
13 | { | ||
14 | } | ||
15 | |||
16 | public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type) | ||
17 | { | ||
18 | } | ||
19 | |||
20 | protected override int FindVersion(DbConnection conn, string type) | ||
21 | { | ||
22 | int version = 0; | ||
23 | using (DbCommand cmd = conn.CreateCommand()) | ||
24 | { | ||
25 | try | ||
26 | { | ||
27 | cmd.CommandText = "select top 1 version from migrations where name = '" + type + "' order by version desc"; //Must be | ||
28 | using (IDataReader reader = cmd.ExecuteReader()) | ||
29 | { | ||
30 | if (reader.Read()) | ||
31 | { | ||
32 | version = Convert.ToInt32(reader["version"]); | ||
33 | } | ||
34 | reader.Close(); | ||
35 | } | ||
36 | } | ||
37 | catch | ||
38 | { | ||
39 | // Something went wrong, so we're version 0 | ||
40 | } | ||
41 | } | ||
42 | return version; | ||
43 | } | ||
44 | } | ||
45 | } | ||
diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 3f85fef..7af3e7e 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs | |||
@@ -42,225 +42,155 @@ namespace OpenSim.Data.MSSQL | |||
42 | /// <summary> | 42 | /// <summary> |
43 | /// A MSSQL Interface for the Region Server. | 43 | /// A MSSQL Interface for the Region Server. |
44 | /// </summary> | 44 | /// </summary> |
45 | public class MSSQLDataStore : IRegionDataStore | 45 | public class MSSQLRegionDataStore : IRegionDataStore |
46 | { | 46 | { |
47 | // private static FileSystemDataStore Instance = new FileSystemDataStore(); | 47 | // private static FileSystemDataStore Instance = new FileSystemDataStore(); |
48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private const string m_primSelect = "select * from prims"; | 50 | private MSSQLManager _Database; |
51 | private const string m_shapeSelect = "select * from primshapes"; | 51 | |
52 | private const string m_itemsSelect = "select * from primitems"; | 52 | // private const string _PrimSelect = "SELECT * FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID = @UUID)"; |
53 | private const string m_terrainSelect = "select top 1 * from terrain"; | 53 | // private const string _ShapeSelect = "SELECT * FROM PRIMSHAPES WHERE UUID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID = @UUID))"; |
54 | private const string m_landSelect = "select * from land"; | 54 | // private const string _ItemsSelect = "SELECT * FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID = @UUID))"; |
55 | private const string m_landAccessListSelect = "select * from landaccesslist"; | 55 | private const string _PrimSelect = "SELECT * FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID IN (@UUID))"; |
56 | 56 | private const string _ShapeSelect = "SELECT * FROM PRIMSHAPES WHERE UUID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID IN (@UUID)))"; | |
57 | private DataSet m_dataSet; | 57 | private const string _ItemsSelect = "SELECT * FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID IN (@UUID)))"; |
58 | private SqlDataAdapter m_primDataAdapter; | 58 | |
59 | private SqlDataAdapter m_shapeDataAdapter; | 59 | private DataSet _PrimsDataSet; |
60 | private SqlDataAdapter m_itemsDataAdapter; | 60 | private SqlDataAdapter _PrimDataAdapter; |
61 | private SqlConnection m_connection; | 61 | private SqlDataAdapter _ShapeDataAdapter; |
62 | private SqlDataAdapter m_terrainDataAdapter; | 62 | private SqlDataAdapter _ItemsDataAdapter; |
63 | private SqlDataAdapter m_landDataAdapter; | ||
64 | private SqlDataAdapter m_landAccessListDataAdapter; | ||
65 | |||
66 | private DataTable m_primTable; | ||
67 | private DataTable m_shapeTable; | ||
68 | private DataTable m_itemsTable; | ||
69 | private DataTable m_terrainTable; | ||
70 | private DataTable m_landTable; | ||
71 | private DataTable m_landAccessListTable; | ||
72 | |||
73 | /// <summary>Temporary attribute while this is experimental</summary> | ||
74 | |||
75 | /*********************************************************************** | ||
76 | * | ||
77 | * Public Interface Functions | ||
78 | * | ||
79 | **********************************************************************/ | ||
80 | 63 | ||
81 | /// <summary> | 64 | /// <summary> |
82 | /// see IRegionDataStore | 65 | /// Initialises the region datastore |
83 | /// </summary> | 66 | /// </summary> |
84 | /// <param name="connectionString"></param> | 67 | /// <param name="connectionString">The connection string.</param> |
85 | public void Initialise(string connectionString) | 68 | public void Initialise(string connectionString) |
86 | { | 69 | { |
87 | // Instance.Initialise("", true); | 70 | if (string.IsNullOrEmpty(connectionString)) |
88 | 71 | { | |
89 | m_dataSet = new DataSet(); | 72 | //Add MSSQLManager (dont know if we need it) |
90 | 73 | _Database = new MSSQLManager(connectionString); | |
91 | m_log.Info("[REGION DB]: MSSql - connecting: " + connectionString); | 74 | } |
92 | m_connection = new SqlConnection(connectionString); | 75 | else |
93 | 76 | { | |
94 | SqlCommand primSelectCmd = new SqlCommand(m_primSelect, m_connection); | 77 | IniFile iniFile = new IniFile("mssql_connection.ini"); |
95 | m_primDataAdapter = new SqlDataAdapter(primSelectCmd); | 78 | string settingDataSource = iniFile.ParseFileReadValue("data_source"); |
96 | 79 | string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); | |
97 | SqlCommand shapeSelectCmd = new SqlCommand(m_shapeSelect, m_connection); | 80 | string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); |
98 | m_shapeDataAdapter = new SqlDataAdapter(shapeSelectCmd); | 81 | string settingUserId = iniFile.ParseFileReadValue("user_id"); |
82 | string settingPassword = iniFile.ParseFileReadValue("password"); | ||
83 | |||
84 | _Database = | ||
85 | new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, | ||
86 | settingPassword); | ||
87 | |||
88 | |||
89 | SqlConnectionStringBuilder conBuilder = new SqlConnectionStringBuilder(); | ||
90 | conBuilder.DataSource = settingDataSource; | ||
91 | conBuilder.InitialCatalog = settingInitialCatalog; | ||
92 | conBuilder.PersistSecurityInfo = Convert.ToBoolean(settingPersistSecurityInfo); | ||
93 | conBuilder.UserID = settingUserId; | ||
94 | conBuilder.Password = settingPassword; | ||
95 | conBuilder.ApplicationName = Assembly.GetEntryAssembly().Location; | ||
96 | |||
97 | connectionString = conBuilder.ToString(); | ||
98 | } | ||
99 | 99 | ||
100 | SqlCommand itemsSelectCmd = new SqlCommand(m_itemsSelect, m_connection); | 100 | //Migration settings |
101 | m_itemsDataAdapter = new SqlDataAdapter(itemsSelectCmd); | 101 | Assembly assem = GetType().Assembly; |
102 | 102 | ||
103 | SqlCommand terrainSelectCmd = new SqlCommand(m_terrainSelect, m_connection); | 103 | using (SqlConnection connection = _Database.DatabaseConnection()) |
104 | m_terrainDataAdapter = new SqlDataAdapter(terrainSelectCmd); | 104 | { |
105 | MSSQLMigration m = new MSSQLMigration(connection, assem, "RegionStore"); | ||
105 | 106 | ||
106 | SqlCommand landSelectCmd = new SqlCommand(m_landSelect, m_connection); | 107 | m.Update(); |
107 | m_landDataAdapter = new SqlDataAdapter(landSelectCmd); | ||
108 | 108 | ||
109 | SqlCommand landAccessListSelectCmd = new SqlCommand(m_landAccessListSelect, m_connection); | 109 | //Create Dataset. Not filled!!! |
110 | m_landAccessListDataAdapter = new SqlDataAdapter(landAccessListSelectCmd); | 110 | _PrimsDataSet = new DataSet("primsdata"); |
111 | 111 | ||
112 | TestTables(m_connection); | 112 | using (SqlCommand primSelectCmd = new SqlCommand(_PrimSelect, connection)) |
113 | { | ||
114 | primSelectCmd.Parameters.AddWithValue("@RegionUUID", ""); | ||
115 | primSelectCmd.Parameters.AddWithValue("@SceneGroupID", "%"); | ||
116 | primSelectCmd.Parameters.AddWithValue("@UUID", ""); | ||
117 | _PrimDataAdapter = new SqlDataAdapter(primSelectCmd); | ||
113 | 118 | ||
114 | lock (m_dataSet) | 119 | DataTable primDataTable = new DataTable("prims"); |
115 | { | 120 | _PrimDataAdapter.Fill(primDataTable); |
116 | m_primTable = createPrimTable(); | 121 | primDataTable.PrimaryKey = new DataColumn[] { primDataTable.Columns["UUID"] }; |
117 | m_dataSet.Tables.Add(m_primTable); | 122 | _PrimsDataSet.Tables.Add(primDataTable); |
118 | setupPrimCommands(m_primDataAdapter, m_connection); | ||
119 | m_primDataAdapter.Fill(m_primTable); | ||
120 | |||
121 | m_shapeTable = createShapeTable(); | ||
122 | m_dataSet.Tables.Add(m_shapeTable); | ||
123 | setupShapeCommands(m_shapeDataAdapter, m_connection); | ||
124 | m_shapeDataAdapter.Fill(m_shapeTable); | ||
125 | |||
126 | m_itemsTable = createItemsTable(); | ||
127 | m_dataSet.Tables.Add(m_itemsTable); | ||
128 | SetupItemsCommands(m_itemsDataAdapter, m_connection); | ||
129 | m_itemsDataAdapter.Fill(m_itemsTable); | ||
130 | |||
131 | m_terrainTable = createTerrainTable(); | ||
132 | m_dataSet.Tables.Add(m_terrainTable); | ||
133 | setupTerrainCommands(m_terrainDataAdapter, m_connection); | ||
134 | m_terrainDataAdapter.Fill(m_terrainTable); | ||
135 | |||
136 | m_landTable = createLandTable(); | ||
137 | m_dataSet.Tables.Add(m_landTable); | ||
138 | setupLandCommands(m_landDataAdapter, m_connection); | ||
139 | m_landDataAdapter.Fill(m_landTable); | ||
140 | |||
141 | m_landAccessListTable = createLandAccessListTable(); | ||
142 | m_dataSet.Tables.Add(m_landAccessListTable); | ||
143 | setupLandAccessCommands(m_landAccessListDataAdapter, m_connection); | ||
144 | m_landAccessListDataAdapter.Fill(m_landAccessListTable); | ||
145 | } | ||
146 | } | ||
147 | 123 | ||
148 | public void StoreRegionSettings(RegionSettings rs) | 124 | SetupCommands(_PrimDataAdapter); //, connection); |
149 | { | 125 | //SetupPrimCommands(_PrimDataAdapter, connection); |
150 | } | ||
151 | 126 | ||
152 | public RegionSettings LoadRegionSettings(LLUUID regionUUID) | 127 | primDataTable.Clear(); |
153 | { | ||
154 | return null; | ||
155 | } | ||
156 | |||
157 | /// <summary> | ||
158 | /// | ||
159 | /// </summary> | ||
160 | /// <param name="obj"></param> | ||
161 | /// <param name="regionUUID"></param> | ||
162 | public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) | ||
163 | { | ||
164 | // Instance.StoreObject(obj, regionUUID); | ||
165 | |||
166 | lock (m_dataSet) | ||
167 | { | ||
168 | foreach (SceneObjectPart prim in obj.Children.Values) | ||
169 | { | ||
170 | if ((prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Physics) == 0 | ||
171 | && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Temporary) == 0 | ||
172 | && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.TemporaryOnRez) == 0) | ||
173 | { | ||
174 | //m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); | ||
175 | addPrim(prim, obj.UUID, regionUUID); | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); | ||
180 | } | ||
181 | } | 128 | } |
182 | } | ||
183 | 129 | ||
184 | Commit(); | 130 | using (SqlCommand shapeSelectCmd = new SqlCommand(_ShapeSelect, connection)) |
185 | } | 131 | { |
132 | shapeSelectCmd.Parameters.AddWithValue("@RegionUUID", ""); | ||
133 | shapeSelectCmd.Parameters.AddWithValue("@SceneGroupID", "%"); | ||
134 | shapeSelectCmd.Parameters.AddWithValue("@UUID", ""); | ||
135 | _ShapeDataAdapter = new SqlDataAdapter(shapeSelectCmd); | ||
186 | 136 | ||
187 | /// <summary> | 137 | DataTable shapeDataTable = new DataTable("primshapes"); |
188 | /// | 138 | _ShapeDataAdapter.Fill(shapeDataTable); |
189 | /// </summary> | 139 | shapeDataTable.PrimaryKey = new DataColumn[] { shapeDataTable.Columns["UUID"] }; |
190 | /// <param name="obj"></param> | 140 | _PrimsDataSet.Tables.Add(shapeDataTable); |
191 | /// <param name="regionUUID"></param> | ||
192 | public void RemoveObject(LLUUID obj, LLUUID regionUUID) | ||
193 | { | ||
194 | // Instance.RemoveObject(obj, regionUUID); | ||
195 | 141 | ||
196 | m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.UUID, regionUUID); | 142 | SetupCommands(_ShapeDataAdapter); //, connection); |
143 | //SetupShapeCommands(_ShapeDataAdapter, connection); | ||
197 | 144 | ||
198 | DataTable prims = m_primTable; | 145 | shapeDataTable.Clear(); |
199 | DataTable shapes = m_shapeTable; | 146 | } |
200 | 147 | ||
201 | string selectExp = "SceneGroupID = '" + obj.ToString() + "'"; | 148 | using (SqlCommand itemSelectCmd = new SqlCommand(_ItemsSelect, connection)) |
202 | lock (m_dataSet) | ||
203 | { | ||
204 | foreach (DataRow row in prims.Select(selectExp)) | ||
205 | { | 149 | { |
206 | // Remove shapes row | 150 | itemSelectCmd.Parameters.AddWithValue("@RegionUUID", ""); |
207 | LLUUID uuid = new LLUUID((string)row["UUID"]); | 151 | itemSelectCmd.Parameters.AddWithValue("@SceneGroupID", "%"); |
152 | itemSelectCmd.Parameters.AddWithValue("@UUID", ""); | ||
153 | _ItemsDataAdapter = new SqlDataAdapter(itemSelectCmd); | ||
208 | 154 | ||
209 | DataRow shapeRow = shapes.Rows.Find(uuid.UUID); | 155 | DataTable itemsDataTable = new DataTable("primitems"); |
210 | if (shapeRow != null) | 156 | _ItemsDataAdapter.Fill(itemsDataTable); |
211 | { | 157 | itemsDataTable.PrimaryKey = new DataColumn[] { itemsDataTable.Columns["itemID"] }; |
212 | shapeRow.Delete(); | 158 | _PrimsDataSet.Tables.Add(itemsDataTable); |
213 | } | ||
214 | 159 | ||
215 | RemoveItems(new LLUUID((string)row["UUID"])); | 160 | SetupCommands(_ItemsDataAdapter); //, connection); |
161 | //SetupItemsCommands(_ItemsDataAdapter, connection); | ||
216 | 162 | ||
217 | // Remove prim row | 163 | itemsDataTable.Clear(); |
218 | row.Delete(); | ||
219 | } | 164 | } |
220 | } | ||
221 | |||
222 | Commit(); | ||
223 | } | ||
224 | |||
225 | /// <summary> | ||
226 | /// Remove all persisted items of the given prim. | ||
227 | /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. | ||
228 | /// </summary> | ||
229 | /// <param name="uuid">The item UUID</param> | ||
230 | private void RemoveItems(LLUUID uuid) | ||
231 | { | ||
232 | String sql = String.Format("primID = '{0}'", uuid); | ||
233 | DataRow[] itemRows = m_itemsTable.Select(sql); | ||
234 | 165 | ||
235 | foreach (DataRow itemRow in itemRows) | 166 | connection.Close(); |
236 | { | ||
237 | itemRow.Delete(); | ||
238 | } | 167 | } |
168 | |||
169 | //After this we have a empty fully configured DataSet. | ||
239 | } | 170 | } |
240 | 171 | ||
241 | /// <summary> | 172 | /// <summary> |
242 | /// Load persisted objects from region storage. | 173 | /// Loads the objects present in the region. |
243 | /// </summary> | 174 | /// </summary> |
244 | /// <param name="regionUUID">The region UUID</param> | 175 | /// <param name="regionUUID">The region UUID.</param> |
176 | /// <returns></returns> | ||
245 | public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID) | 177 | public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID) |
246 | { | 178 | { |
247 | // return Instance.LoadObjects(regionUUID); | ||
248 | |||
249 | Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>(); | 179 | Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>(); |
250 | 180 | ||
251 | List<SceneObjectGroup> retvals = new List<SceneObjectGroup>(); | 181 | //Retrieve all values of current region |
182 | RetrievePrimsDataForRegion(regionUUID, LLUUID.Zero, ""); | ||
252 | 183 | ||
253 | DataTable prims = m_primTable; | 184 | List<SceneObjectGroup> retvals = new List<SceneObjectGroup>(); |
254 | DataTable shapes = m_shapeTable; | ||
255 | 185 | ||
256 | string byRegion = "RegionUUID = '" + regionUUID.ToString() + "'"; | 186 | DataTable prims = _PrimsDataSet.Tables["prims"]; |
257 | string orderByParent = "ParentID ASC"; | 187 | DataTable shapes = _PrimsDataSet.Tables["primshapes"]; |
258 | 188 | ||
259 | lock (m_dataSet) | 189 | lock (_PrimsDataSet) |
260 | { | 190 | { |
261 | DataRow[] primsForRegion = prims.Select(byRegion, orderByParent); | 191 | DataRow[] primsForRegion = prims.Select("", "ParentID ASC"); //.Select(byRegion, orderByParent); |
262 | m_log.Info("[REGION DB]: " + | 192 | |
263 | "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); | 193 | _Log.Info("[REGION DB]: " + "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); |
264 | 194 | ||
265 | foreach (DataRow primRow in primsForRegion) | 195 | foreach (DataRow primRow in primsForRegion) |
266 | { | 196 | { |
@@ -275,14 +205,14 @@ namespace OpenSim.Data.MSSQL | |||
275 | { | 205 | { |
276 | SceneObjectGroup group = new SceneObjectGroup(); | 206 | SceneObjectGroup group = new SceneObjectGroup(); |
277 | 207 | ||
278 | DataRow shapeRow = shapes.Rows.Find(prim.UUID); | 208 | DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); |
279 | if (shapeRow != null) | 209 | if (shapeRow != null) |
280 | { | 210 | { |
281 | prim.Shape = buildShape(shapeRow); | 211 | prim.Shape = buildShape(shapeRow); |
282 | } | 212 | } |
283 | else | 213 | else |
284 | { | 214 | { |
285 | m_log.Info( | 215 | _Log.Info( |
286 | "No shape found for prim in storage, so setting default box shape"); | 216 | "No shape found for prim in storage, so setting default box shape"); |
287 | prim.Shape = PrimitiveBaseShape.Default; | 217 | prim.Shape = PrimitiveBaseShape.Default; |
288 | } | 218 | } |
@@ -294,572 +224,712 @@ namespace OpenSim.Data.MSSQL | |||
294 | } | 224 | } |
295 | else | 225 | else |
296 | { | 226 | { |
297 | DataRow shapeRow = shapes.Rows.Find(prim.UUID); | 227 | DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); |
298 | if (shapeRow != null) | 228 | if (shapeRow != null) |
299 | { | 229 | { |
300 | prim.Shape = buildShape(shapeRow); | 230 | prim.Shape = buildShape(shapeRow); |
301 | } | 231 | } |
302 | else | 232 | else |
303 | { | 233 | { |
304 | m_log.Info( | 234 | _Log.Info( |
305 | "No shape found for prim in storage, so setting default box shape"); | 235 | "No shape found for prim in storage, so setting default box shape"); |
306 | prim.Shape = PrimitiveBaseShape.Default; | 236 | prim.Shape = PrimitiveBaseShape.Default; |
307 | } | 237 | } |
308 | createdObjects[new LLUUID(objID)].AddPart(prim); | 238 | createdObjects[new LLUUID(objID)].AddPart(prim); |
309 | } | 239 | } |
310 | 240 | ||
311 | LoadItems(prim); | 241 | LoadItems(prim); |
312 | } | 242 | } |
313 | catch (Exception e) | 243 | catch (Exception e) |
314 | { | 244 | { |
315 | m_log.Error("[DATASTORE]: Failed create prim object, exception and data follows"); | 245 | _Log.Error("[REGION DB]: Failed create prim object, exception and data follows"); |
316 | m_log.Info("[DATASTORE]: " + e.ToString()); | 246 | _Log.Info("[REGION DB]: " + e.ToString()); |
317 | foreach (DataColumn col in prims.Columns) | 247 | foreach (DataColumn col in prims.Columns) |
318 | { | 248 | { |
319 | m_log.Info("[DATASTORE]: Col: " + col.ColumnName + " => " + primRow[col]); | 249 | _Log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); |
320 | } | 250 | } |
321 | } | 251 | } |
322 | } | 252 | } |
253 | |||
254 | _PrimsDataSet.Tables["prims"].Clear(); | ||
255 | _PrimsDataSet.Tables["primshapes"].Clear(); | ||
256 | _PrimsDataSet.Tables["primitems"].Clear(); | ||
323 | } | 257 | } |
324 | return retvals; | 258 | return retvals; |
259 | |||
260 | #region Experimental | ||
261 | |||
262 | // | ||
263 | // //Get all prims | ||
264 | // string sql = "select * from prims where RegionUUID = @RegionUUID"; | ||
265 | // | ||
266 | // using (AutoClosingSqlCommand cmdPrims = _Database.Query(sql)) | ||
267 | // { | ||
268 | // cmdPrims.Parameters.AddWithValue("@RegionUUID", regionUUID.ToString()); | ||
269 | // using (SqlDataReader readerPrims = cmdPrims.ExecuteReader()) | ||
270 | // { | ||
271 | // while (readerPrims.Read()) | ||
272 | // { | ||
273 | // string uuid = (string)readerPrims["UUID"]; | ||
274 | // string objID = (string)readerPrims["SceneGroupID"]; | ||
275 | // SceneObjectPart prim = buildPrim(readerPrims); | ||
276 | // | ||
277 | // //Setting default shape, will change shape ltr | ||
278 | // prim.Shape = PrimitiveBaseShape.Default; | ||
279 | // | ||
280 | // //Load inventory items of prim | ||
281 | // //LoadItems(prim); | ||
282 | // | ||
283 | // if (uuid == objID) | ||
284 | // { | ||
285 | // SceneObjectGroup group = new SceneObjectGroup(); | ||
286 | // | ||
287 | // group.AddPart(prim); | ||
288 | // group.RootPart = prim; | ||
289 | // | ||
290 | // createdObjects.Add(group.UUID, group); | ||
291 | // retvals.Add(group); | ||
292 | // } | ||
293 | // else | ||
294 | // { | ||
295 | // createdObjects[new LLUUID(objID)].AddPart(prim); | ||
296 | // } | ||
297 | // } | ||
298 | // } | ||
299 | // } | ||
300 | // m_log.Info("[REGION DB]: Loaded " + retvals.Count + " prim objects for region: " + regionUUID); | ||
301 | // | ||
302 | // //Find all shapes related with prims | ||
303 | // sql = "select * from primshapes"; | ||
304 | // using (AutoClosingSqlCommand cmdShapes = _Database.Query(sql)) | ||
305 | // { | ||
306 | // using (SqlDataReader readerShapes = cmdShapes.ExecuteReader()) | ||
307 | // { | ||
308 | // while (readerShapes.Read()) | ||
309 | // { | ||
310 | // LLUUID UUID = new LLUUID((string) readerShapes["UUID"]); | ||
311 | // | ||
312 | // foreach (SceneObjectGroup objectGroup in createdObjects.Values) | ||
313 | // { | ||
314 | // if (objectGroup.Children.ContainsKey(UUID)) | ||
315 | // { | ||
316 | // objectGroup.Children[UUID].Shape = buildShape(readerShapes); | ||
317 | // } | ||
318 | // } | ||
319 | // } | ||
320 | // } | ||
321 | // } | ||
322 | // return retvals; | ||
323 | |||
324 | #endregion | ||
325 | } | 325 | } |
326 | 326 | ||
327 | /// <summary> | 327 | public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) |
328 | /// Load in a prim's persisted inventory. | ||
329 | /// </summary> | ||
330 | /// <param name="prim"></param> | ||
331 | private void LoadItems(SceneObjectPart prim) | ||
332 | { | 328 | { |
333 | //m_log.InfoFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID); | 329 | //Retrieve all values of current region, and current scene/or prims |
334 | 330 | //Build primID's, we use IN so I can select all prims from objgroup | |
335 | DataTable dbItems = m_itemsTable; | 331 | string primID = ""; |
332 | foreach (SceneObjectPart prim in obj.Children.Values) | ||
333 | { | ||
334 | primID += prim.UUID + "', '"; | ||
335 | } | ||
336 | primID = primID.Remove(primID.LastIndexOf("',")); | ||
336 | 337 | ||
337 | String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); | 338 | RetrievePrimsDataForRegion(regionUUID, obj.UUID, primID); |
338 | DataRow[] dbItemRows = dbItems.Select(sql); | ||
339 | 339 | ||
340 | IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); | 340 | _Log.InfoFormat("[REGION DB]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); |
341 | 341 | ||
342 | foreach (DataRow row in dbItemRows) | 342 | foreach (SceneObjectPart prim in obj.Children.Values) |
343 | { | 343 | { |
344 | TaskInventoryItem item = buildItem(row); | 344 | if ((prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Physics) == 0 |
345 | inventory.Add(item); | 345 | && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Temporary) == 0 |
346 | && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.TemporaryOnRez) == 0) | ||
347 | { | ||
348 | lock (_PrimsDataSet) | ||
349 | { | ||
350 | DataTable prims = _PrimsDataSet.Tables["prims"]; | ||
351 | DataTable shapes = _PrimsDataSet.Tables["primshapes"]; | ||
346 | 352 | ||
347 | //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); | 353 | DataRow primRow = prims.Rows.Find(prim.UUID.ToString()); |
354 | if (primRow == null) | ||
355 | { | ||
356 | primRow = prims.NewRow(); | ||
357 | fillPrimRow(primRow, prim, obj.UUID, regionUUID); | ||
358 | prims.Rows.Add(primRow); | ||
359 | } | ||
360 | else | ||
361 | { | ||
362 | fillPrimRow(primRow, prim, obj.UUID, regionUUID); | ||
363 | } | ||
364 | |||
365 | DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); | ||
366 | if (shapeRow == null) | ||
367 | { | ||
368 | shapeRow = shapes.NewRow(); | ||
369 | fillShapeRow(shapeRow, prim); | ||
370 | shapes.Rows.Add(shapeRow); | ||
371 | } | ||
372 | else | ||
373 | { | ||
374 | fillShapeRow(shapeRow, prim); | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | else | ||
379 | { | ||
380 | // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); | ||
381 | } | ||
348 | } | 382 | } |
349 | 383 | ||
350 | prim.RestoreInventoryItems(inventory); | 384 | //Save changes |
385 | CommitDataSet(); | ||
386 | } | ||
351 | 387 | ||
352 | // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in | 388 | /// <summary> |
353 | // every item). This data should really be stored in the prim table itself. | 389 | /// Removes a object from the database. |
354 | if (dbItemRows.Length > 0) | 390 | /// Meaning removing it from tables Prims, PrimShapes and PrimItems |
391 | /// </summary> | ||
392 | /// <param name="objectID">id of scenegroup</param> | ||
393 | /// <param name="regionUUID">regionUUID (is this used anyway</param> | ||
394 | public void RemoveObject(LLUUID objectID, LLUUID regionUUID) | ||
395 | { | ||
396 | _Log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", objectID, regionUUID); | ||
397 | |||
398 | //Remove from prims and primsitem table | ||
399 | string sqlPrims = string.Format("DELETE FROM PRIMS WHERE SceneGroupID = '{0}'", objectID); | ||
400 | string sqlPrimItems = string.Format("DELETE FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE SceneGroupID = '{0}')", objectID); | ||
401 | string sqlPrimShapes = string.Format("DELETE FROM PRIMSHAPES WHERE uuid in (SELECT UUID FROM PRIMS WHERE SceneGroupID = '{0}')", objectID); | ||
402 | |||
403 | //Using the non transaction mode. | ||
404 | using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) | ||
355 | { | 405 | { |
356 | prim.FolderID = inventory[0].ParentID; | 406 | cmd.ExecuteNonQuery(); |
407 | |||
408 | cmd.CommandText = sqlPrimItems; | ||
409 | cmd.ExecuteNonQuery(); | ||
410 | |||
411 | cmd.CommandText = sqlPrims; | ||
412 | cmd.ExecuteNonQuery(); | ||
357 | } | 413 | } |
358 | } | 414 | } |
359 | 415 | ||
360 | /// <summary> | 416 | /// <summary> |
361 | /// Store a terrain revision in region storage. | 417 | /// Store the inventory of a prim. Warning deletes everything first and then adds all again. |
362 | /// </summary> | 418 | /// </summary> |
363 | /// <param name="ter">HeightField data</param> | 419 | /// <param name="primID"></param> |
364 | /// <param name="regionID">Region UUID</param> | 420 | /// <param name="items"></param> |
365 | public void StoreTerrain(double[,] ter, LLUUID regionID) | 421 | public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items) |
366 | { | 422 | { |
367 | int revision = Util.UnixTimeSinceEpoch(); | 423 | _Log.InfoFormat("[REGION DB]: Persisting Prim Inventory with prim ID {0}", primID); |
368 | m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString()); | 424 | |
425 | //Statement from MySQL section! | ||
426 | // For now, we're just going to crudely remove all the previous inventory items | ||
427 | // no matter whether they have changed or not, and replace them with the current set. | ||
369 | 428 | ||
370 | // DataTable terrain = m_dataSet.Tables["terrain"]; | 429 | //Delete everything from PrimID |
371 | lock (m_dataSet) | 430 | //TODO add index on PrimID in DB, if not already exist |
431 | using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) | ||
372 | { | 432 | { |
373 | SqlCommand cmd = new SqlCommand("insert into terrain(RegionUUID, Revision, Heightfield)" + | 433 | cmd.Parameters.AddWithValue("@primID", primID.ToString()); |
374 | " values(@RegionUUID, @Revision, @Heightfield)", m_connection); | 434 | cmd.ExecuteNonQuery(); |
375 | using (cmd) | 435 | } |
436 | |||
437 | string sql = | ||
438 | "INSERT INTO [primitems] ([itemID],[primID],[assetID],[parentFolderID],[invType],[assetType],[name],[description],[creationDate],[creatorID],[ownerID],[lastOwnerID],[groupID],[nextPermissions],[currentPermissions],[basePermissions],[everyonePermissions],[groupPermissions],[flags]) VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID,@lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; | ||
439 | |||
440 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
441 | { | ||
442 | foreach (TaskInventoryItem newItem in items) | ||
376 | { | 443 | { |
377 | cmd.Parameters.Add(new SqlParameter("@RegionUUID", regionID.UUID)); | 444 | // |
378 | cmd.Parameters.Add(new SqlParameter("@Revision", revision)); | 445 | cmd.Parameters.AddRange(CreatePrimInventoryParameters(newItem)); |
379 | cmd.Parameters.Add(new SqlParameter("@Heightfield", serializeTerrain(ter))); | 446 | |
380 | cmd.ExecuteNonQuery(); | 447 | cmd.ExecuteNonQuery(); |
448 | |||
449 | cmd.Parameters.Clear(); | ||
381 | } | 450 | } |
382 | } | 451 | } |
383 | } | 452 | } |
384 | 453 | ||
385 | /// <summary> | 454 | /// <summary> |
386 | /// Load the latest terrain revision from region storage. | 455 | /// Loads the terrain map. |
387 | /// </summary> | 456 | /// </summary> |
388 | /// <param name="regionID">The Region UUID</param> | 457 | /// <param name="regionID">regionID.</param> |
389 | /// <returns>HeightField Data</returns> | 458 | /// <returns></returns> |
390 | public double[,] LoadTerrain(LLUUID regionID) | 459 | public double[,] LoadTerrain(LLUUID regionID) |
391 | { | 460 | { |
392 | double[,] terret = new double[256, 256]; | 461 | double[,] terrain = new double[256, 256]; |
393 | terret.Initialize(); | 462 | terrain.Initialize(); |
394 | 463 | ||
395 | SqlCommand cmd = new SqlCommand( | 464 | string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; |
396 | @"select top 1 RegionUUID, Revision, Heightfield from terrain | ||
397 | where RegionUUID=@RegionUUID order by Revision desc" | ||
398 | , m_connection); | ||
399 | 465 | ||
400 | // SqlParameter param = new SqlParameter(); | 466 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) |
401 | cmd.Parameters.Add(new SqlParameter("@RegionUUID", regionID.UUID)); | ||
402 | |||
403 | if (m_connection.State != ConnectionState.Open) | ||
404 | { | 467 | { |
405 | m_connection.Open(); | 468 | // MySqlParameter param = new MySqlParameter(); |
406 | } | 469 | cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); |
407 | 470 | ||
408 | using (SqlDataReader row = cmd.ExecuteReader()) | 471 | using (SqlDataReader reader = cmd.ExecuteReader()) |
409 | { | ||
410 | int rev = 0; | ||
411 | if (row.Read()) | ||
412 | { | 472 | { |
413 | MemoryStream str = new MemoryStream((byte[])row["Heightfield"]); | 473 | int rev = 0; |
414 | BinaryReader br = new BinaryReader(str); | 474 | if (reader.Read()) |
415 | for (int x = 0; x < 256; x++) | ||
416 | { | 475 | { |
417 | for (int y = 0; y < 256; y++) | 476 | MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); |
477 | BinaryReader br = new BinaryReader(str); | ||
478 | for (int x = 0; x < 256; x++) | ||
418 | { | 479 | { |
419 | terret[x, y] = br.ReadDouble(); | 480 | for (int y = 0; y < 256; y++) |
481 | { | ||
482 | terrain[x, y] = br.ReadDouble(); | ||
483 | } | ||
420 | } | 484 | } |
485 | rev = (int)reader["Revision"]; | ||
421 | } | 486 | } |
422 | rev = (int)row["Revision"]; | 487 | else |
423 | } | 488 | { |
424 | else | 489 | _Log.Info("[REGION DB]: No terrain found for region"); |
425 | { | 490 | return null; |
426 | m_log.Info("[REGION DB]: No terrain found for region"); | 491 | } |
427 | return null; | 492 | _Log.Info("[REGION DB]: Loaded terrain revision r" + rev); |
428 | } | 493 | } |
429 | |||
430 | m_log.Info("[REGION DB]: Loaded terrain revision r" + rev.ToString()); | ||
431 | } | 494 | } |
432 | 495 | ||
433 | return terret; | 496 | return terrain; |
434 | } | 497 | } |
435 | 498 | ||
436 | /// <summary> | 499 | /// <summary> |
437 | /// | 500 | /// Stores the terrain map to DB. |
438 | /// </summary> | 501 | /// </summary> |
439 | /// <param name="globalID"></param> | 502 | /// <param name="terrain">terrain map data.</param> |
440 | public void RemoveLandObject(LLUUID globalID) | 503 | /// <param name="regionID">regionID.</param> |
504 | public void StoreTerrain(double[,] terrain, LLUUID regionID) | ||
441 | { | 505 | { |
442 | // Instance.RemoveLandObject(globalID); | 506 | int revision = Util.UnixTimeSinceEpoch(); |
443 | 507 | ||
444 | lock (m_dataSet) | 508 | //Delete old terrain map |
509 | string sql = "delete from terrain where RegionUUID=@RegionUUID"; | ||
510 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
445 | { | 511 | { |
446 | using (SqlCommand cmd = new SqlCommand("delete from land where UUID=@UUID", m_connection)) | 512 | cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); |
447 | { | 513 | cmd.ExecuteNonQuery(); |
448 | cmd.Parameters.Add(new SqlParameter("@UUID", globalID.UUID)); | 514 | } |
449 | cmd.ExecuteNonQuery(); | ||
450 | } | ||
451 | 515 | ||
452 | using ( | 516 | sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + |
453 | SqlCommand cmd = new SqlCommand("delete from landaccesslist where LandUUID=@UUID", m_connection) | 517 | " values(@RegionUUID, @Revision, @Heightfield)"; |
454 | ) | 518 | |
455 | { | 519 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) |
456 | cmd.Parameters.Add(new SqlParameter("@UUID", globalID.UUID)); | 520 | { |
457 | cmd.ExecuteNonQuery(); | 521 | cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); |
458 | } | 522 | cmd.Parameters.AddWithValue("@Revision", revision); |
523 | cmd.Parameters.AddWithValue("@Heightfield", serializeTerrain(terrain)); | ||
524 | cmd.ExecuteNonQuery(); | ||
459 | } | 525 | } |
526 | |||
527 | _Log.Info("[REGION DB]: Stored terrain revision r" + revision); | ||
460 | } | 528 | } |
461 | 529 | ||
462 | /// <summary> | 530 | /// <summary> |
463 | /// | 531 | /// Loads all the land objects of a region. |
464 | /// </summary> | 532 | /// </summary> |
465 | /// <param name="parcel"></param> | 533 | /// <param name="regionUUID">The region UUID.</param> |
466 | public void StoreLandObject(ILandObject parcel) | 534 | /// <returns></returns> |
535 | public List<LandData> LoadLandObjects(LLUUID regionUUID) | ||
467 | { | 536 | { |
468 | lock (m_dataSet) | 537 | List<LandData> landDataForRegion = new List<LandData>(); |
538 | |||
539 | string sql = "select * from land where RegionUUID = @RegionUUID"; | ||
540 | |||
541 | //Retrieve all land data from region | ||
542 | using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) | ||
469 | { | 543 | { |
470 | DataTable land = m_landTable; | 544 | cmdLandData.Parameters.AddWithValue("@RegionUUID", regionUUID.ToString()); |
471 | DataTable landaccesslist = m_landAccessListTable; | ||
472 | 545 | ||
473 | DataRow landRow = land.Rows.Find(parcel.landData.GlobalID.UUID); | 546 | using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) |
474 | if (landRow == null) | ||
475 | { | ||
476 | landRow = land.NewRow(); | ||
477 | fillLandRow(landRow, parcel.landData, parcel.regionUUID); | ||
478 | land.Rows.Add(landRow); | ||
479 | } | ||
480 | else | ||
481 | { | 547 | { |
482 | fillLandRow(landRow, parcel.landData, parcel.regionUUID); | 548 | while (readerLandData.Read()) |
483 | } | 549 | { |
550 | LandData data = buildLandData(readerLandData); | ||
484 | 551 | ||
485 | using ( | 552 | } |
486 | SqlCommand cmd = | ||
487 | new SqlCommand("delete from landaccesslist where LandUUID=@LandUUID", m_connection)) | ||
488 | { | ||
489 | cmd.Parameters.Add(new SqlParameter("@LandUUID", parcel.landData.GlobalID.UUID)); | ||
490 | cmd.ExecuteNonQuery(); | ||
491 | } | 553 | } |
554 | } | ||
492 | 555 | ||
493 | foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.ParcelAccessList) | 556 | //Retrieve all accesslist data for all landdata |
557 | foreach (LandData landData in landDataForRegion) | ||
558 | { | ||
559 | sql = "select * from landaccesslist where LandUUID = @LandUUID"; | ||
560 | using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) | ||
494 | { | 561 | { |
495 | DataRow newAccessRow = landaccesslist.NewRow(); | 562 | cmdAccessList.Parameters.AddWithValue("@LandUUID", landData.GlobalID); |
496 | fillLandAccessRow(newAccessRow, entry, parcel.landData.GlobalID); | 563 | using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) |
497 | landaccesslist.Rows.Add(newAccessRow); | 564 | { |
565 | while (readerAccessList.Read()) | ||
566 | { | ||
567 | landData.ParcelAccessList.Add(buildLandAccessData(readerAccessList)); | ||
568 | } | ||
569 | } | ||
498 | } | 570 | } |
499 | |||
500 | } | 571 | } |
501 | Commit(); | 572 | |
573 | //Return data | ||
574 | return landDataForRegion; | ||
502 | } | 575 | } |
503 | 576 | ||
504 | /// <summary> | 577 | /// <summary> |
505 | /// | 578 | /// Stores land object with landaccess list. |
506 | /// </summary> | 579 | /// </summary> |
507 | /// <param name="regionUUID">The region UUID</param> | 580 | /// <param name="parcel">parcel data.</param> |
508 | /// <returns></returns> | 581 | public void StoreLandObject(ILandObject parcel) |
509 | public List<LandData> LoadLandObjects(LLUUID regionUUID) | ||
510 | { | 582 | { |
511 | List<LandData> landDataForRegion = new List<LandData>(); | 583 | //As this is only one record in land table I just delete all and then add a new record. |
512 | lock (m_dataSet) | 584 | //As the delete landaccess is already in the mysql code |
585 | |||
586 | //Delete old values | ||
587 | RemoveLandObject(parcel.landData.GlobalID); | ||
588 | |||
589 | //Insert new values | ||
590 | string sql = @"INSERT INTO [land] | ||
591 | ([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID]) | ||
592 | VALUES | ||
593 | (@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID)"; | ||
594 | |||
595 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
513 | { | 596 | { |
514 | DataTable land = m_landTable; | 597 | cmd.Parameters.AddRange(CreateLandParameters(parcel.landData, parcel.regionUUID)); |
515 | DataTable landaccesslist = m_landAccessListTable; | 598 | |
516 | string searchExp = "RegionUUID = '" + regionUUID.UUID + "'"; | 599 | cmd.ExecuteNonQuery(); |
517 | DataRow[] rawDataForRegion = land.Select(searchExp); | 600 | } |
518 | foreach (DataRow rawDataLand in rawDataForRegion) | 601 | |
602 | sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; | ||
603 | |||
604 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
605 | { | ||
606 | foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.landData.ParcelAccessList) | ||
519 | { | 607 | { |
520 | LandData newLand = buildLandData(rawDataLand); | 608 | cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.regionUUID)); |
521 | string accessListSearchExp = "LandUUID = '" + newLand.GlobalID.UUID + "'"; | 609 | |
522 | DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp); | 610 | cmd.ExecuteNonQuery(); |
523 | foreach (DataRow rawDataLandAccess in rawDataForLandAccessList) | ||
524 | { | ||
525 | newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess)); | ||
526 | } | ||
527 | 611 | ||
528 | landDataForRegion.Add(newLand); | 612 | cmd.Parameters.Clear(); |
529 | } | 613 | } |
530 | } | 614 | } |
531 | return landDataForRegion; | ||
532 | } | 615 | } |
533 | 616 | ||
534 | /// <summary> | 617 | /// <summary> |
535 | /// Load (fetch?) the region banlist | 618 | /// Removes a land object from DB. |
536 | /// </summary> | 619 | /// </summary> |
537 | /// <param name="regionUUID">the region UUID</param> | 620 | /// <param name="globalID">UUID of landobject</param> |
538 | /// <returns>the banlist list</returns> | 621 | public void RemoveLandObject(LLUUID globalID) |
539 | public List<EstateBan> LoadRegionBanList(LLUUID regionUUID) | ||
540 | { | 622 | { |
541 | List<EstateBan> regionbanlist = new List<EstateBan>(); | 623 | using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) |
542 | return regionbanlist; | 624 | { |
625 | cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); | ||
626 | cmd.ExecuteNonQuery(); | ||
627 | } | ||
628 | |||
629 | using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) | ||
630 | { | ||
631 | cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); | ||
632 | cmd.ExecuteNonQuery(); | ||
633 | } | ||
543 | } | 634 | } |
544 | 635 | ||
545 | /// <summary> | 636 | /// <summary> |
546 | /// STUB, add an item into region banlist | 637 | /// Loads the settings of a region. |
547 | /// </summary> | 638 | /// </summary> |
548 | /// <param name="item">the item</param> | 639 | /// <param name="regionUUID">The region UUID.</param> |
549 | public void AddToRegionBanlist(EstateBan item) | 640 | /// <returns></returns> |
641 | public RegionSettings LoadRegionSettings(LLUUID regionUUID) | ||
550 | { | 642 | { |
643 | string sql = "select * from regionsettings where regionUUID = @regionUUID"; | ||
644 | RegionSettings regionSettings; | ||
645 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
646 | { | ||
647 | cmd.Parameters.AddWithValue("@regionUUID", regionUUID.ToString()); | ||
648 | using(SqlDataReader reader = cmd.ExecuteReader()) | ||
649 | { | ||
650 | if (reader.Read()) | ||
651 | { | ||
652 | regionSettings = buildRegionSettings(reader); | ||
653 | regionSettings.OnSave += StoreRegionSettings; | ||
551 | 654 | ||
552 | } | 655 | return regionSettings; |
656 | } | ||
657 | } | ||
658 | } | ||
553 | 659 | ||
554 | /// <summary> | 660 | //If comes here then there is now region setting for that region |
555 | /// STUB, remove an item from region banlist | 661 | regionSettings = new RegionSettings(); |
556 | /// </summary> | 662 | regionSettings.RegionUUID = regionUUID; |
557 | /// <param name="item"></param> | 663 | regionSettings.OnSave += StoreRegionSettings; |
558 | public void RemoveFromRegionBanlist(EstateBan item) | ||
559 | { | ||
560 | 664 | ||
665 | //Store new values | ||
666 | StoreNewRegionSettings(regionSettings); | ||
667 | |||
668 | return regionSettings; | ||
561 | } | 669 | } |
562 | 670 | ||
563 | /// <summary> | 671 | /// <summary> |
564 | /// Commit | 672 | /// Store region settings, need to check if the check is really necesary. If we can make something for creating new region. |
565 | /// </summary> | 673 | /// </summary> |
566 | public void Commit() | 674 | /// <param name="regionSettings">region settings.</param> |
675 | public void StoreRegionSettings(RegionSettings regionSettings) | ||
567 | { | 676 | { |
568 | if (m_connection.State != ConnectionState.Open) | 677 | //Little check if regionUUID already exist in DB |
678 | string regionUUID = null; | ||
679 | using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) | ||
569 | { | 680 | { |
570 | m_connection.Open(); | 681 | regionUUID = cmd.ExecuteScalar().ToString(); |
571 | } | 682 | } |
572 | 683 | ||
573 | lock (m_dataSet) | 684 | if (string.IsNullOrEmpty(regionUUID)) |
574 | { | 685 | { |
575 | // DisplayDataSet(m_dataSet, "Region DataSet"); | 686 | StoreNewRegionSettings(regionSettings); |
576 | 687 | } | |
577 | m_primDataAdapter.Update(m_primTable); | 688 | else |
578 | m_shapeDataAdapter.Update(m_shapeTable); | 689 | { |
579 | 690 | //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB | |
580 | m_itemsDataAdapter.Update(m_itemsTable); | 691 | string sql = |
581 | 692 | @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage | |
582 | m_terrainDataAdapter.Update(m_terrainTable); | 693 | ,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide |
583 | m_landDataAdapter.Update(m_landTable); | 694 | ,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity |
584 | m_landAccessListDataAdapter.Update(m_landAccessListTable); | 695 | ,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics |
696 | ,[terrain_texture_1] = @terrain_texture_1 ,[terrain_texture_2] = @terrain_texture_2 ,[terrain_texture_3] = @terrain_texture_3 | ||
697 | ,[terrain_texture_4] = @terrain_texture_4 ,[elevation_1_nw] = @elevation_1_nw ,[elevation_2_nw] = @elevation_2_nw | ||
698 | ,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se | ||
699 | ,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit | ||
700 | ,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position | ||
701 | ,[covenant] = @covenant ,[Sandbox] = @Sandbox WHERE [regionUUID] = @regionUUID"; | ||
702 | |||
703 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
704 | { | ||
705 | cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); | ||
585 | 706 | ||
586 | m_dataSet.AcceptChanges(); | 707 | cmd.ExecuteNonQuery(); |
708 | } | ||
587 | } | 709 | } |
588 | } | 710 | } |
589 | 711 | ||
590 | /// <summary> | ||
591 | /// See <see cref="Commit"/> | ||
592 | /// </summary> | ||
593 | public void Shutdown() | 712 | public void Shutdown() |
594 | { | 713 | { |
595 | Commit(); | 714 | //Not used?? |
596 | } | 715 | } |
597 | 716 | ||
598 | /*********************************************************************** | 717 | #region Private Methods |
599 | * | ||
600 | * Database Definition Functions | ||
601 | * | ||
602 | * This should be db agnostic as we define them in ADO.NET terms | ||
603 | * | ||
604 | **********************************************************************/ | ||
605 | |||
606 | /// <summary> | ||
607 | /// | ||
608 | /// </summary> | ||
609 | /// <param name="dt"></param> | ||
610 | /// <param name="name"></param> | ||
611 | /// <param name="type"></param> | ||
612 | /// <returns></returns> | ||
613 | private static DataColumn createCol(DataTable dt, string name, Type type) | ||
614 | { | ||
615 | DataColumn col = new DataColumn(name, type); | ||
616 | dt.Columns.Add(col); | ||
617 | return col; | ||
618 | } | ||
619 | 718 | ||
620 | /// <summary> | 719 | /// <summary> |
621 | /// Create the "terrain" table | 720 | /// Load in a prim's persisted inventory. |
622 | /// </summary> | 721 | /// </summary> |
623 | /// <returns>the datatable</returns> | 722 | /// <param name="prim">The prim</param> |
624 | private static DataTable createTerrainTable() | 723 | private void LoadItems(SceneObjectPart prim) |
625 | { | 724 | { |
626 | DataTable terrain = new DataTable("terrain"); | 725 | DataTable dbItems = _PrimsDataSet.Tables["primitems"]; |
627 | 726 | ||
628 | createCol(terrain, "RegionUUID", typeof(String)); | 727 | String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); |
629 | createCol(terrain, "Revision", typeof(Int32)); | 728 | DataRow[] dbItemRows = dbItems.Select(sql); |
630 | createCol(terrain, "Heightfield", typeof(Byte[])); | ||
631 | |||
632 | return terrain; | ||
633 | } | ||
634 | 729 | ||
635 | /// <summary> | 730 | IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); |
636 | /// Create the "prims" table | ||
637 | /// </summary> | ||
638 | /// <returns>the datatable</returns> | ||
639 | private static DataTable createPrimTable() | ||
640 | { | ||
641 | DataTable prims = new DataTable("prims"); | ||
642 | |||
643 | createCol(prims, "UUID", typeof(String)); | ||
644 | createCol(prims, "RegionUUID", typeof(String)); | ||
645 | createCol(prims, "ParentID", typeof(Int32)); | ||
646 | createCol(prims, "CreationDate", typeof(Int32)); | ||
647 | createCol(prims, "Name", typeof(String)); | ||
648 | createCol(prims, "SceneGroupID", typeof(String)); | ||
649 | // various text fields | ||
650 | createCol(prims, "Text", typeof(String)); | ||
651 | createCol(prims, "Description", typeof(String)); | ||
652 | createCol(prims, "SitName", typeof(String)); | ||
653 | createCol(prims, "TouchName", typeof(String)); | ||
654 | // permissions | ||
655 | createCol(prims, "ObjectFlags", typeof(Int32)); | ||
656 | createCol(prims, "CreatorID", typeof(String)); | ||
657 | createCol(prims, "OwnerID", typeof(String)); | ||
658 | createCol(prims, "GroupID", typeof(String)); | ||
659 | createCol(prims, "LastOwnerID", typeof(String)); | ||
660 | createCol(prims, "OwnerMask", typeof(Int32)); | ||
661 | createCol(prims, "NextOwnerMask", typeof(Int32)); | ||
662 | createCol(prims, "GroupMask", typeof(Int32)); | ||
663 | createCol(prims, "EveryoneMask", typeof(Int32)); | ||
664 | createCol(prims, "BaseMask", typeof(Int32)); | ||
665 | // vectors | ||
666 | createCol(prims, "PositionX", typeof(Double)); | ||
667 | createCol(prims, "PositionY", typeof(Double)); | ||
668 | createCol(prims, "PositionZ", typeof(Double)); | ||
669 | createCol(prims, "GroupPositionX", typeof(Double)); | ||
670 | createCol(prims, "GroupPositionY", typeof(Double)); | ||
671 | createCol(prims, "GroupPositionZ", typeof(Double)); | ||
672 | createCol(prims, "VelocityX", typeof(Double)); | ||
673 | createCol(prims, "VelocityY", typeof(Double)); | ||
674 | createCol(prims, "VelocityZ", typeof(Double)); | ||
675 | createCol(prims, "AngularVelocityX", typeof(Double)); | ||
676 | createCol(prims, "AngularVelocityY", typeof(Double)); | ||
677 | createCol(prims, "AngularVelocityZ", typeof(Double)); | ||
678 | createCol(prims, "AccelerationX", typeof(Double)); | ||
679 | createCol(prims, "AccelerationY", typeof(Double)); | ||
680 | createCol(prims, "AccelerationZ", typeof(Double)); | ||
681 | // quaternions | ||
682 | createCol(prims, "RotationX", typeof(Double)); | ||
683 | createCol(prims, "RotationY", typeof(Double)); | ||
684 | createCol(prims, "RotationZ", typeof(Double)); | ||
685 | createCol(prims, "RotationW", typeof(Double)); | ||
686 | 731 | ||
687 | // sit target | 732 | foreach (DataRow row in dbItemRows) |
688 | createCol(prims, "SitTargetOffsetX", typeof(Double)); | 733 | { |
689 | createCol(prims, "SitTargetOffsetY", typeof(Double)); | 734 | TaskInventoryItem item = buildItem(row); |
690 | createCol(prims, "SitTargetOffsetZ", typeof(Double)); | 735 | inventory.Add(item); |
691 | 736 | ||
692 | createCol(prims, "SitTargetOrientW", typeof(Double)); | 737 | //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); |
693 | createCol(prims, "SitTargetOrientX", typeof(Double)); | 738 | } |
694 | createCol(prims, "SitTargetOrientY", typeof(Double)); | ||
695 | createCol(prims, "SitTargetOrientZ", typeof(Double)); | ||
696 | 739 | ||
697 | // Add in contraints | 740 | prim.RestoreInventoryItems(inventory); |
698 | prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; | ||
699 | 741 | ||
700 | return prims; | 742 | // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in |
743 | // every item). This data should really be stored in the prim table itself. | ||
744 | if (dbItemRows.Length > 0) | ||
745 | { | ||
746 | prim.FolderID = inventory[0].ParentID; | ||
747 | } | ||
701 | } | 748 | } |
702 | 749 | ||
703 | /// <summary> | 750 | /// <summary> |
704 | /// Create the "land" table | 751 | /// Serializes the terrain data for storage in DB. |
705 | /// </summary> | 752 | /// </summary> |
706 | /// <returns>the datatable</returns> | 753 | /// <param name="val">terrain data</param> |
707 | private static DataTable createLandTable() | 754 | /// <returns></returns> |
755 | private static Array serializeTerrain(double[,] val) | ||
708 | { | 756 | { |
709 | DataTable land = new DataTable("land"); | 757 | MemoryStream str = new MemoryStream(65536 * sizeof(double)); |
710 | createCol(land, "UUID", typeof(String)); | 758 | BinaryWriter bw = new BinaryWriter(str); |
711 | createCol(land, "RegionUUID", typeof(String)); | ||
712 | createCol(land, "LocalLandID", typeof(Int32)); | ||
713 | 759 | ||
714 | // Bitmap is a byte[512] | 760 | // TODO: COMPATIBILITY - Add byte-order conversions |
715 | createCol(land, "Bitmap", typeof(Byte[])); | 761 | for (int x = 0; x < 256; x++) |
716 | 762 | for (int y = 0; y < 256; y++) | |
717 | createCol(land, "Name", typeof(String)); | 763 | { |
718 | createCol(land, "Description", typeof(String)); | 764 | double height = val[x, y]; |
719 | createCol(land, "OwnerUUID", typeof(String)); | 765 | if (height == 0.0) |
720 | createCol(land, "IsGroupOwned", typeof(Int32)); | 766 | height = double.Epsilon; |
721 | createCol(land, "Area", typeof(Int32)); | 767 | |
722 | createCol(land, "AuctionID", typeof(Int32)); //Unemplemented | 768 | bw.Write(height); |
723 | createCol(land, "Category", typeof(Int32)); //Enum libsecondlife.Parcel.ParcelCategory | 769 | } |
724 | createCol(land, "ClaimDate", typeof(Int32)); | 770 | |
725 | createCol(land, "ClaimPrice", typeof(Int32)); | 771 | return str.ToArray(); |
726 | createCol(land, "GroupUUID", typeof(String)); | ||
727 | createCol(land, "SalePrice", typeof(Int32)); | ||
728 | createCol(land, "LandStatus", typeof(Int32)); //Enum. libsecondlife.Parcel.ParcelStatus | ||
729 | createCol(land, "LandFlags", typeof(Int32)); | ||
730 | createCol(land, "LandingType", typeof(Int32)); | ||
731 | createCol(land, "MediaAutoScale", typeof(Int32)); | ||
732 | createCol(land, "MediaTextureUUID", typeof(String)); | ||
733 | createCol(land, "MediaURL", typeof(String)); | ||
734 | createCol(land, "MusicURL", typeof(String)); | ||
735 | createCol(land, "PassHours", typeof(Double)); | ||
736 | createCol(land, "PassPrice", typeof(Int32)); | ||
737 | createCol(land, "SnapshotUUID", typeof(String)); | ||
738 | createCol(land, "UserLocationX", typeof(Double)); | ||
739 | createCol(land, "UserLocationY", typeof(Double)); | ||
740 | createCol(land, "UserLocationZ", typeof(Double)); | ||
741 | createCol(land, "UserLookAtX", typeof(Double)); | ||
742 | createCol(land, "UserLookAtY", typeof(Double)); | ||
743 | createCol(land, "UserLookAtZ", typeof(Double)); | ||
744 | |||
745 | land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; | ||
746 | |||
747 | return land; | ||
748 | } | 772 | } |
749 | 773 | ||
750 | /// <summary> | 774 | /// <summary> |
751 | /// Create "landacceslist" table | 775 | /// Stores new regionsettings. |
752 | /// </summary> | 776 | /// </summary> |
753 | /// <returns>the datatable</returns> | 777 | /// <param name="regionSettings">The region settings.</param> |
754 | private static DataTable createLandAccessListTable() | 778 | private void StoreNewRegionSettings(RegionSettings regionSettings) |
755 | { | 779 | { |
756 | DataTable landaccess = new DataTable("landaccesslist"); | 780 | string sql = @"INSERT INTO [regionsettings] |
757 | createCol(landaccess, "LandUUID", typeof(String)); | 781 | ([regionUUID],[block_terraform],[block_fly],[allow_damage],[restrict_pushing],[allow_land_resell],[allow_land_join_divide],[block_show_in_search],[agent_limit],[object_bonus],[maturity],[disable_scripts],[disable_collisions],[disable_physics],[terrain_texture_1],[terrain_texture_2],[terrain_texture_3],[terrain_texture_4],[elevation_1_nw],[elevation_2_nw],[elevation_1_ne],[elevation_2_ne],[elevation_1_se],[elevation_2_se],[elevation_1_sw],[elevation_2_sw],[water_height],[terrain_raise_limit],[terrain_lower_limit],[use_estate_sun],[fixed_sun],[sun_position],[covenant],[Sandbox]) VALUES |
758 | createCol(landaccess, "AccessUUID", typeof(String)); | 782 | (@regionUUID,@block_terraform,@block_fly,@allow_damage,@restrict_pushing,@allow_land_resell,@allow_land_join_divide,@block_show_in_search,@agent_limit,@object_bonus,@maturity,@disable_scripts,@disable_collisions,@disable_physics,@terrain_texture_1,@terrain_texture_2,@terrain_texture_3,@terrain_texture_4,@elevation_1_nw,@elevation_2_nw,@elevation_1_ne,@elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit,@terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@Sandbox)"; |
759 | createCol(landaccess, "Flags", typeof(Int32)); | 783 | |
784 | using (AutoClosingSqlCommand cmd = _Database.Query(sql)) | ||
785 | { | ||
786 | cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); | ||
760 | 787 | ||
761 | return landaccess; | 788 | cmd.ExecuteNonQuery(); |
789 | } | ||
762 | } | 790 | } |
763 | 791 | ||
792 | #region Private DataRecord conversion methods | ||
793 | |||
764 | /// <summary> | 794 | /// <summary> |
765 | /// Create "primsshapes" table | 795 | /// Builds the region settings from a datarecod. |
766 | /// </summary> | 796 | /// </summary> |
767 | /// <returns>the datatable</returns> | 797 | /// <param name="row">datarecord with regionsettings.</param> |
768 | private static DataTable createShapeTable() | 798 | /// <returns></returns> |
799 | private static RegionSettings buildRegionSettings(IDataRecord row) | ||
769 | { | 800 | { |
770 | DataTable shapes = new DataTable("primshapes"); | 801 | //TODO change this is some more generic code so we doesnt have to change it every time a new field is added? |
771 | createCol(shapes, "UUID", typeof(String)); | 802 | RegionSettings newSettings = new RegionSettings(); |
772 | // shape is an enum | 803 | |
773 | createCol(shapes, "Shape", typeof(Int32)); | 804 | newSettings.RegionUUID = new LLUUID((string)row["regionUUID"]); |
774 | // vectors | 805 | newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); |
775 | createCol(shapes, "ScaleX", typeof(Double)); | 806 | newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); |
776 | createCol(shapes, "ScaleY", typeof(Double)); | 807 | newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); |
777 | createCol(shapes, "ScaleZ", typeof(Double)); | 808 | newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); |
778 | // paths | 809 | newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); |
779 | createCol(shapes, "PCode", typeof(Int32)); | 810 | newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); |
780 | createCol(shapes, "PathBegin", typeof(Int32)); | 811 | newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); |
781 | createCol(shapes, "PathEnd", typeof(Int32)); | 812 | newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); |
782 | createCol(shapes, "PathScaleX", typeof(Int32)); | 813 | newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); |
783 | createCol(shapes, "PathScaleY", typeof(Int32)); | 814 | newSettings.Maturity = Convert.ToInt32(row["maturity"]); |
784 | createCol(shapes, "PathShearX", typeof(Int32)); | 815 | newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); |
785 | createCol(shapes, "PathShearY", typeof(Int32)); | 816 | newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); |
786 | createCol(shapes, "PathSkew", typeof(Int32)); | 817 | newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); |
787 | createCol(shapes, "PathCurve", typeof(Int32)); | 818 | newSettings.TerrainTexture1 = new LLUUID((String)row["terrain_texture_1"]); |
788 | createCol(shapes, "PathRadiusOffset", typeof(Int32)); | 819 | newSettings.TerrainTexture2 = new LLUUID((String)row["terrain_texture_2"]); |
789 | createCol(shapes, "PathRevolutions", typeof(Int32)); | 820 | newSettings.TerrainTexture3 = new LLUUID((String)row["terrain_texture_3"]); |
790 | createCol(shapes, "PathTaperX", typeof(Int32)); | 821 | newSettings.TerrainTexture4 = new LLUUID((String)row["terrain_texture_4"]); |
791 | createCol(shapes, "PathTaperY", typeof(Int32)); | 822 | newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); |
792 | createCol(shapes, "PathTwist", typeof(Int32)); | 823 | newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); |
793 | createCol(shapes, "PathTwistBegin", typeof(Int32)); | 824 | newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); |
794 | // profile | 825 | newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); |
795 | createCol(shapes, "ProfileBegin", typeof(Int32)); | 826 | newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); |
796 | createCol(shapes, "ProfileEnd", typeof(Int32)); | 827 | newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); |
797 | createCol(shapes, "ProfileCurve", typeof(Int32)); | 828 | newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); |
798 | createCol(shapes, "ProfileHollow", typeof(Int32)); | 829 | newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); |
799 | createCol(shapes, "State", typeof(Int32)); | 830 | newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); |
800 | // text TODO: this isn't right, but I'm not sure the right | 831 | newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); |
801 | // way to specify this as a blob atm | 832 | newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); |
802 | createCol(shapes, "Texture", typeof(Byte[])); | 833 | newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); |
803 | createCol(shapes, "ExtraParams", typeof(Byte[])); | 834 | newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); |
804 | 835 | newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); | |
805 | shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] }; | 836 | newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); |
806 | 837 | newSettings.Covenant = new LLUUID((String)row["covenant"]); | |
807 | return shapes; | 838 | |
839 | return newSettings; | ||
808 | } | 840 | } |
809 | 841 | ||
810 | /// <summary> | 842 | /// <summary> |
811 | /// Create "primitems" table | 843 | /// Builds the land data from a datarecord. |
812 | /// </summary> | 844 | /// </summary> |
813 | /// <returns>the datatable</returns> | 845 | /// <param name="row">datarecord with land data</param> |
814 | private static DataTable createItemsTable() | 846 | /// <returns></returns> |
847 | private static LandData buildLandData(IDataRecord row) | ||
815 | { | 848 | { |
816 | DataTable items = new DataTable("primitems"); | 849 | LandData newData = new LandData(); |
817 | 850 | ||
818 | createCol(items, "itemID", typeof(String)); | 851 | newData.GlobalID = new LLUUID((String)row["UUID"]); |
819 | createCol(items, "primID", typeof(String)); | 852 | newData.LocalID = Convert.ToInt32(row["LocalLandID"]); |
820 | createCol(items, "assetID", typeof(String)); | 853 | |
821 | createCol(items, "parentFolderID", typeof(String)); | 854 | // Bitmap is a byte[512] |
855 | newData.Bitmap = (Byte[])row["Bitmap"]; | ||
856 | |||
857 | newData.Name = (String)row["Name"]; | ||
858 | newData.Description = (String)row["Description"]; | ||
859 | newData.OwnerID = (String)row["OwnerUUID"]; | ||
860 | newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); | ||
861 | newData.Area = Convert.ToInt32(row["Area"]); | ||
862 | newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented | ||
863 | newData.Category = (Parcel.ParcelCategory)Convert.ToInt32(row["Category"]); | ||
864 | //Enum libsecondlife.Parcel.ParcelCategory | ||
865 | newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); | ||
866 | newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); | ||
867 | newData.GroupID = new LLUUID((String)row["GroupUUID"]); | ||
868 | newData.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
869 | newData.Status = (Parcel.ParcelStatus)Convert.ToInt32(row["LandStatus"]); | ||
870 | //Enum. libsecondlife.Parcel.ParcelStatus | ||
871 | newData.Flags = Convert.ToUInt32(row["LandFlags"]); | ||
872 | newData.LandingType = Convert.ToByte(row["LandingType"]); | ||
873 | newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); | ||
874 | newData.MediaID = new LLUUID((String)row["MediaTextureUUID"]); | ||
875 | newData.MediaURL = (String)row["MediaURL"]; | ||
876 | newData.MusicURL = (String)row["MusicURL"]; | ||
877 | newData.PassHours = Convert.ToSingle(row["PassHours"]); | ||
878 | newData.PassPrice = Convert.ToInt32(row["PassPrice"]); | ||
822 | 879 | ||
823 | createCol(items, "invType", typeof(Int32)); | 880 | LLUUID authedbuyer; |
824 | createCol(items, "assetType", typeof(Int32)); | 881 | LLUUID snapshotID; |
825 | 882 | ||
826 | createCol(items, "name", typeof(String)); | 883 | if (LLUUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) |
827 | createCol(items, "description", typeof(String)); | 884 | newData.AuthBuyerID = authedbuyer; |
828 | 885 | ||
829 | createCol(items, "creationDate", typeof(Int64)); | 886 | if (LLUUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) |
830 | createCol(items, "creatorID", typeof(String)); | 887 | newData.SnapshotID = snapshotID; |
831 | createCol(items, "ownerID", typeof(String)); | ||
832 | createCol(items, "lastOwnerID", typeof(String)); | ||
833 | createCol(items, "groupID", typeof(String)); | ||
834 | 888 | ||
835 | createCol(items, "nextPermissions", typeof(Int32)); | 889 | try |
836 | createCol(items, "currentPermissions", typeof(Int32)); | 890 | { |
837 | createCol(items, "basePermissions", typeof(Int32)); | 891 | newData.UserLocation = |
838 | createCol(items, "everyonePermissions", typeof(Int32)); | 892 | new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), |
839 | createCol(items, "groupPermissions", typeof(Int32)); | 893 | Convert.ToSingle(row["UserLocationZ"])); |
840 | // createCol(items, "flags", typeof(Int32)); | 894 | newData.UserLookAt = |
895 | new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), | ||
896 | Convert.ToSingle(row["UserLookAtZ"])); | ||
897 | } | ||
898 | catch (InvalidCastException) | ||
899 | { | ||
900 | newData.UserLocation = LLVector3.Zero; | ||
901 | newData.UserLookAt = LLVector3.Zero; | ||
902 | _Log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); | ||
903 | } | ||
841 | 904 | ||
842 | items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] }; | 905 | newData.ParcelAccessList = new List<ParcelManager.ParcelAccessEntry>(); |
843 | 906 | ||
844 | return items; | 907 | return newData; |
845 | } | 908 | } |
846 | 909 | ||
847 | /*********************************************************************** | 910 | /// <summary> |
848 | * | 911 | /// Builds the landaccess data from a data record. |
849 | * Convert between ADO.NET <=> OpenSim Objects | 912 | /// </summary> |
850 | * | 913 | /// <param name="row">datarecord with landaccess data</param> |
851 | * These should be database independant | 914 | /// <returns></returns> |
852 | * | 915 | private static ParcelManager.ParcelAccessEntry buildLandAccessData(IDataRecord row) |
853 | **********************************************************************/ | 916 | { |
917 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | ||
918 | entry.AgentID = new LLUUID((string)row["AccessUUID"]); | ||
919 | entry.Flags = (ParcelManager.AccessList)Convert.ToInt32(row["Flags"]); | ||
920 | entry.Time = new DateTime(); | ||
921 | return entry; | ||
922 | } | ||
854 | 923 | ||
855 | /// <summary> | 924 | /// <summary> |
856 | /// | 925 | /// Builds the prim from a datarecord. |
857 | /// </summary> | 926 | /// </summary> |
858 | /// <param name="row"></param> | 927 | /// <param name="row">datarecord</param> |
859 | /// <returns></returns> | 928 | /// <returns></returns> |
860 | private SceneObjectPart buildPrim(DataRow row) | 929 | private static SceneObjectPart buildPrim(DataRow row) |
861 | { | 930 | { |
862 | SceneObjectPart prim = new SceneObjectPart(); | 931 | SceneObjectPart prim = new SceneObjectPart(); |
932 | |||
863 | prim.UUID = new LLUUID((String)row["UUID"]); | 933 | prim.UUID = new LLUUID((String)row["UUID"]); |
864 | // explicit conversion of integers is required, which sort | 934 | // explicit conversion of integers is required, which sort |
865 | // of sucks. No idea if there is a shortcut here or not. | 935 | // of sucks. No idea if there is a shortcut here or not. |
@@ -915,330 +985,73 @@ namespace OpenSim.Data.MSSQL | |||
915 | Convert.ToSingle(row["RotationZ"]), | 985 | Convert.ToSingle(row["RotationZ"]), |
916 | Convert.ToSingle(row["RotationW"]) | 986 | Convert.ToSingle(row["RotationW"]) |
917 | ); | 987 | ); |
918 | try | 988 | prim.SitTargetPositionLL = new LLVector3( |
919 | { | 989 | Convert.ToSingle(row["SitTargetOffsetX"]), |
920 | prim.SitTargetPositionLL = new LLVector3( | 990 | Convert.ToSingle(row["SitTargetOffsetY"]), |
921 | Convert.ToSingle(row["SitTargetOffsetX"]), | 991 | Convert.ToSingle(row["SitTargetOffsetZ"]) |
922 | Convert.ToSingle(row["SitTargetOffsetY"]), | 992 | ); |
923 | Convert.ToSingle(row["SitTargetOffsetZ"])); | 993 | prim.SitTargetOrientationLL = new LLQuaternion( |
924 | prim.SitTargetOrientationLL = new LLQuaternion( | 994 | Convert.ToSingle(row["SitTargetOrientX"]), |
925 | Convert.ToSingle( | 995 | Convert.ToSingle(row["SitTargetOrientY"]), |
926 | row["SitTargetOrientX"]), | 996 | Convert.ToSingle(row["SitTargetOrientZ"]), |
927 | Convert.ToSingle( | 997 | Convert.ToSingle(row["SitTargetOrientW"]) |
928 | row["SitTargetOrientY"]), | 998 | ); |
929 | Convert.ToSingle( | ||
930 | row["SitTargetOrientZ"]), | ||
931 | Convert.ToSingle( | ||
932 | row["SitTargetOrientW"])); | ||
933 | } | ||
934 | catch (InvalidCastException) | ||
935 | { | ||
936 | // Database table was created before we got here and now has null values :P | ||
937 | |||
938 | using ( | ||
939 | SqlCommand cmd = | ||
940 | new SqlCommand( | ||
941 | "ALTER TABLE [prims] ADD COLUMN [SitTargetOffsetX] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetY] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetZ] float NOT NULL default 0, ADD COLUMN [SitTargetOrientW] float NOT NULL default 0, ADD COLUMN [SitTargetOrientX] float NOT NULL default 0, ADD COLUMN [SitTargetOrientY] float NOT NULL default 0, ADD COLUMN [SitTargetOrientZ] float NOT NULL default 0;", | ||
942 | m_connection)) | ||
943 | { | ||
944 | cmd.ExecuteNonQuery(); | ||
945 | } | ||
946 | } | ||
947 | |||
948 | return prim; | ||
949 | } | ||
950 | |||
951 | /// <summary> | ||
952 | /// Build a prim inventory item from the persisted data. | ||
953 | /// </summary> | ||
954 | /// <param name="row"></param> | ||
955 | /// <returns></returns> | ||
956 | private static TaskInventoryItem buildItem(DataRow row) | ||
957 | { | ||
958 | TaskInventoryItem taskItem = new TaskInventoryItem(); | ||
959 | |||
960 | taskItem.ItemID = new LLUUID((String)row["itemID"]); | ||
961 | taskItem.ParentPartID = new LLUUID((String)row["primID"]); | ||
962 | taskItem.AssetID = new LLUUID((String)row["assetID"]); | ||
963 | taskItem.ParentID = new LLUUID((String)row["parentFolderID"]); | ||
964 | |||
965 | taskItem.InvType = Convert.ToInt32(row["invType"]); | ||
966 | taskItem.Type = Convert.ToInt32(row["assetType"]); | ||
967 | |||
968 | taskItem.Name = (String)row["name"]; | ||
969 | taskItem.Description = (String)row["description"]; | ||
970 | taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); | ||
971 | taskItem.CreatorID = new LLUUID((String)row["creatorID"]); | ||
972 | taskItem.OwnerID = new LLUUID((String)row["ownerID"]); | ||
973 | taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]); | ||
974 | taskItem.GroupID = new LLUUID((String)row["groupID"]); | ||
975 | |||
976 | taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); | ||
977 | taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); | ||
978 | taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); | ||
979 | taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); | ||
980 | taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); | ||
981 | // taskItem.Flags = Convert.ToUInt32(row["flags"]); | ||
982 | |||
983 | return taskItem; | ||
984 | } | ||
985 | |||
986 | /// <summary> | ||
987 | /// | ||
988 | /// </summary> | ||
989 | /// <param name="row"></param> | ||
990 | /// <returns></returns> | ||
991 | private static LandData buildLandData(DataRow row) | ||
992 | { | ||
993 | LandData newData = new LandData(); | ||
994 | 999 | ||
995 | newData.GlobalID = new LLUUID((String)row["UUID"]); | 1000 | prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); |
996 | newData.LocalID = Convert.ToInt32(row["LocalLandID"]); | 1001 | prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); |
1002 | prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); | ||
1003 | prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); | ||
1004 | prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); | ||
997 | 1005 | ||
998 | // Bitmap is a byte[512] | 1006 | prim.Sound = new LLUUID(row["LoopedSound"].ToString()); |
999 | newData.Bitmap = (Byte[])row["Bitmap"]; | 1007 | prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); |
1008 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1000 | 1009 | ||
1001 | newData.Name = (String)row["Name"]; | 1010 | if (row["TextureAnimation"] != null && row["TextureAnimation"] != DBNull.Value) |
1002 | newData.Description = (String)row["Description"]; | 1011 | prim.TextureAnimation = (Byte[])row["TextureAnimation"]; |
1003 | newData.OwnerID = (String)row["OwnerUUID"]; | ||
1004 | newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); | ||
1005 | newData.Area = Convert.ToInt32(row["Area"]); | ||
1006 | newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented | ||
1007 | newData.Category = (Parcel.ParcelCategory)Convert.ToInt32(row["Category"]); | ||
1008 | //Enum libsecondlife.Parcel.ParcelCategory | ||
1009 | newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); | ||
1010 | newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); | ||
1011 | newData.GroupID = new LLUUID((String)row["GroupUUID"]); | ||
1012 | newData.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
1013 | newData.Status = (Parcel.ParcelStatus)Convert.ToInt32(row["LandStatus"]); | ||
1014 | //Enum. libsecondlife.Parcel.ParcelStatus | ||
1015 | newData.Flags = Convert.ToUInt32(row["LandFlags"]); | ||
1016 | newData.LandingType = Convert.ToByte(row["LandingType"]); | ||
1017 | newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); | ||
1018 | newData.MediaID = new LLUUID((String)row["MediaTextureUUID"]); | ||
1019 | newData.MediaURL = (String)row["MediaURL"]; | ||
1020 | newData.MusicURL = (String)row["MusicURL"]; | ||
1021 | newData.PassHours = Convert.ToSingle(row["PassHours"]); | ||
1022 | newData.PassPrice = Convert.ToInt32(row["PassPrice"]); | ||
1023 | newData.SnapshotID = (String)row["SnapshotUUID"]; | ||
1024 | |||
1025 | newData.UserLocation = | ||
1026 | new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), | ||
1027 | Convert.ToSingle(row["UserLocationZ"])); | ||
1028 | newData.UserLookAt = | ||
1029 | new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), | ||
1030 | Convert.ToSingle(row["UserLookAtZ"])); | ||
1031 | newData.ParcelAccessList = new List<ParcelManager.ParcelAccessEntry>(); | ||
1032 | 1012 | ||
1033 | return newData; | 1013 | prim.RotationalVelocity = new LLVector3( |
1034 | } | 1014 | Convert.ToSingle(row["OmegaX"]), |
1035 | 1015 | Convert.ToSingle(row["OmegaY"]), | |
1036 | /// <summary> | 1016 | Convert.ToSingle(row["OmegaZ"]) |
1037 | /// | 1017 | ); |
1038 | /// </summary> | ||
1039 | /// <param name="row"></param> | ||
1040 | /// <returns></returns> | ||
1041 | private static ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row) | ||
1042 | { | ||
1043 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | ||
1044 | entry.AgentID = new LLUUID((string)row["AccessUUID"]); | ||
1045 | entry.Flags = (ParcelManager.AccessList)Convert.ToInt32(row["Flags"]); | ||
1046 | entry.Time = new DateTime(); | ||
1047 | return entry; | ||
1048 | } | ||
1049 | |||
1050 | /// <summary> | ||
1051 | /// Serialize terrain HeightField | ||
1052 | /// </summary> | ||
1053 | /// <param name="val">the terrain heightfield</param> | ||
1054 | /// <returns></returns> | ||
1055 | private static Array serializeTerrain(double[,] val) | ||
1056 | { | ||
1057 | MemoryStream str = new MemoryStream(65536 * sizeof(double)); | ||
1058 | BinaryWriter bw = new BinaryWriter(str); | ||
1059 | 1018 | ||
1060 | // TODO: COMPATIBILITY - Add byte-order conversions | 1019 | // TODO: Rotation |
1061 | for (int x = 0; x < 256; x++) | 1020 | // OmegaX, OmegaY, OmegaZ |
1062 | for (int y = 0; y < 256; y++) | ||
1063 | bw.Write(val[x, y]); | ||
1064 | 1021 | ||
1065 | return str.ToArray(); | 1022 | prim.SetCameraEyeOffset(new LLVector3( |
1066 | } | 1023 | Convert.ToSingle(row["CameraEyeOffsetX"]), |
1024 | Convert.ToSingle(row["CameraEyeOffsetY"]), | ||
1025 | Convert.ToSingle(row["CameraEyeOffsetZ"]) | ||
1026 | )); | ||
1067 | 1027 | ||
1068 | /// <summary> | 1028 | prim.SetCameraAtOffset(new LLVector3( |
1069 | /// | 1029 | Convert.ToSingle(row["CameraAtOffsetX"]), |
1070 | /// </summary> | 1030 | Convert.ToSingle(row["CameraAtOffsetY"]), |
1071 | /// <param name="row"></param> | 1031 | Convert.ToSingle(row["CameraAtOffsetZ"]) |
1072 | /// <param name="prim"></param> | 1032 | )); |
1073 | /// <param name="sceneGroupID"></param> | ||
1074 | /// <param name="regionUUID"></param> | ||
1075 | private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) | ||
1076 | { | ||
1077 | row["UUID"] = prim.UUID; | ||
1078 | row["RegionUUID"] = regionUUID; | ||
1079 | row["ParentID"] = prim.ParentID; | ||
1080 | row["CreationDate"] = prim.CreationDate; | ||
1081 | row["Name"] = prim.Name; | ||
1082 | row["SceneGroupID"] = sceneGroupID; | ||
1083 | // the UUID of the root part for this SceneObjectGroup | ||
1084 | // various text fields | ||
1085 | row["Text"] = prim.Text; | ||
1086 | row["Description"] = prim.Description; | ||
1087 | row["SitName"] = prim.SitName; | ||
1088 | row["TouchName"] = prim.TouchName; | ||
1089 | // permissions | ||
1090 | row["ObjectFlags"] = prim.ObjectFlags; | ||
1091 | row["CreatorID"] = prim.CreatorID; | ||
1092 | row["OwnerID"] = prim.OwnerID; | ||
1093 | row["GroupID"] = prim.GroupID; | ||
1094 | row["LastOwnerID"] = prim.LastOwnerID; | ||
1095 | row["OwnerMask"] = prim.OwnerMask; | ||
1096 | row["NextOwnerMask"] = prim.NextOwnerMask; | ||
1097 | row["GroupMask"] = prim.GroupMask; | ||
1098 | row["EveryoneMask"] = prim.EveryoneMask; | ||
1099 | row["BaseMask"] = prim.BaseMask; | ||
1100 | // vectors | ||
1101 | row["PositionX"] = prim.OffsetPosition.X; | ||
1102 | row["PositionY"] = prim.OffsetPosition.Y; | ||
1103 | row["PositionZ"] = prim.OffsetPosition.Z; | ||
1104 | row["GroupPositionX"] = prim.GroupPosition.X; | ||
1105 | row["GroupPositionY"] = prim.GroupPosition.Y; | ||
1106 | row["GroupPositionZ"] = prim.GroupPosition.Z; | ||
1107 | row["VelocityX"] = prim.Velocity.X; | ||
1108 | row["VelocityY"] = prim.Velocity.Y; | ||
1109 | row["VelocityZ"] = prim.Velocity.Z; | ||
1110 | row["AngularVelocityX"] = prim.AngularVelocity.X; | ||
1111 | row["AngularVelocityY"] = prim.AngularVelocity.Y; | ||
1112 | row["AngularVelocityZ"] = prim.AngularVelocity.Z; | ||
1113 | row["AccelerationX"] = prim.Acceleration.X; | ||
1114 | row["AccelerationY"] = prim.Acceleration.Y; | ||
1115 | row["AccelerationZ"] = prim.Acceleration.Z; | ||
1116 | // quaternions | ||
1117 | row["RotationX"] = prim.RotationOffset.X; | ||
1118 | row["RotationY"] = prim.RotationOffset.Y; | ||
1119 | row["RotationZ"] = prim.RotationOffset.Z; | ||
1120 | row["RotationW"] = prim.RotationOffset.W; | ||
1121 | 1033 | ||
1122 | try | 1034 | if (Convert.ToInt16(row["ForceMouselook"]) != 0) |
1123 | { | 1035 | prim.SetForceMouselook(true); |
1124 | // Sit target | ||
1125 | LLVector3 sitTargetPos = prim.SitTargetPositionLL; | ||
1126 | row["SitTargetOffsetX"] = sitTargetPos.X; | ||
1127 | row["SitTargetOffsetY"] = sitTargetPos.Y; | ||
1128 | row["SitTargetOffsetZ"] = sitTargetPos.Z; | ||
1129 | |||
1130 | LLQuaternion sitTargetOrient = prim.SitTargetOrientationLL; | ||
1131 | row["SitTargetOrientW"] = sitTargetOrient.W; | ||
1132 | row["SitTargetOrientX"] = sitTargetOrient.X; | ||
1133 | row["SitTargetOrientY"] = sitTargetOrient.Y; | ||
1134 | row["SitTargetOrientZ"] = sitTargetOrient.Z; | ||
1135 | } | ||
1136 | catch (Exception) | ||
1137 | { | ||
1138 | // Database table was created before we got here and needs to be created! :P | ||
1139 | 1036 | ||
1140 | using ( | 1037 | prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); |
1141 | SqlCommand cmd = | ||
1142 | new SqlCommand( | ||
1143 | "ALTER TABLE [prims] ADD COLUMN [SitTargetOffsetX] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetY] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetZ] float NOT NULL default 0, ADD COLUMN [SitTargetOrientW] float NOT NULL default 0, ADD COLUMN [SitTargetOrientX] float NOT NULL default 0, ADD COLUMN [SitTargetOrientY] float NOT NULL default 0, ADD COLUMN [SitTargetOrientZ] float NOT NULL default 0;", | ||
1144 | m_connection)) | ||
1145 | { | ||
1146 | cmd.ExecuteNonQuery(); | ||
1147 | } | ||
1148 | } | ||
1149 | } | ||
1150 | 1038 | ||
1151 | /// <summary> | 1039 | if (Convert.ToInt16(row["AllowedDrop"]) != 0) |
1152 | /// | 1040 | prim.AllowedDrop = true; |
1153 | /// </summary> | ||
1154 | /// <param name="row"></param> | ||
1155 | /// <param name="taskItem"></param> | ||
1156 | private static void fillItemRow(DataRow row, TaskInventoryItem taskItem) | ||
1157 | { | ||
1158 | row["itemID"] = taskItem.ItemID; | ||
1159 | row["primID"] = taskItem.ParentPartID; | ||
1160 | row["assetID"] = taskItem.AssetID; | ||
1161 | row["parentFolderID"] = taskItem.ParentID; | ||
1162 | |||
1163 | row["invType"] = taskItem.InvType; | ||
1164 | row["assetType"] = taskItem.Type; | ||
1165 | |||
1166 | row["name"] = taskItem.Name; | ||
1167 | row["description"] = taskItem.Description; | ||
1168 | row["creationDate"] = taskItem.CreationDate; | ||
1169 | row["creatorID"] = taskItem.CreatorID; | ||
1170 | row["ownerID"] = taskItem.OwnerID; | ||
1171 | row["lastOwnerID"] = taskItem.LastOwnerID; | ||
1172 | row["groupID"] = taskItem.GroupID; | ||
1173 | row["nextPermissions"] = taskItem.NextPermissions; | ||
1174 | row["currentPermissions"] = taskItem.CurrentPermissions; | ||
1175 | row["basePermissions"] = taskItem.BasePermissions; | ||
1176 | row["everyonePermissions"] = taskItem.EveryonePermissions; | ||
1177 | row["groupPermissions"] = taskItem.GroupPermissions; | ||
1178 | // row["flags"] = taskItem.Flags; | ||
1179 | } | ||
1180 | 1041 | ||
1181 | /// <summary> | 1042 | if (Convert.ToInt16(row["DieAtEdge"]) != 0) |
1182 | /// | 1043 | prim.DIE_AT_EDGE = true; |
1183 | /// </summary> | ||
1184 | /// <param name="row"></param> | ||
1185 | /// <param name="land"></param> | ||
1186 | /// <param name="regionUUID"></param> | ||
1187 | private static void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) | ||
1188 | { | ||
1189 | row["UUID"] = land.GlobalID.UUID; | ||
1190 | row["RegionUUID"] = regionUUID.UUID; | ||
1191 | row["LocalLandID"] = land.LocalID; | ||
1192 | 1044 | ||
1193 | // Bitmap is a byte[512] | 1045 | prim.SalePrice = Convert.ToInt32(row["SalePrice"]); |
1194 | row["Bitmap"] = land.Bitmap; | 1046 | prim.ObjectSaleType = Convert.ToByte(row["SaleType"]); |
1195 | |||
1196 | row["Name"] = land.Name; | ||
1197 | row["Description"] = land.Description; | ||
1198 | row["OwnerUUID"] = land.OwnerID.UUID; | ||
1199 | row["IsGroupOwned"] = land.IsGroupOwned; | ||
1200 | row["Area"] = land.Area; | ||
1201 | row["AuctionID"] = land.AuctionID; //Unemplemented | ||
1202 | row["Category"] = land.Category; //Enum libsecondlife.Parcel.ParcelCategory | ||
1203 | row["ClaimDate"] = land.ClaimDate; | ||
1204 | row["ClaimPrice"] = land.ClaimPrice; | ||
1205 | row["GroupUUID"] = land.GroupID.UUID; | ||
1206 | row["SalePrice"] = land.SalePrice; | ||
1207 | row["LandStatus"] = land.Status; //Enum. libsecondlife.Parcel.ParcelStatus | ||
1208 | row["LandFlags"] = land.Flags; | ||
1209 | row["LandingType"] = land.LandingType; | ||
1210 | row["MediaAutoScale"] = land.MediaAutoScale; | ||
1211 | row["MediaTextureUUID"] = land.MediaID.UUID; | ||
1212 | row["MediaURL"] = land.MediaURL; | ||
1213 | row["MusicURL"] = land.MusicURL; | ||
1214 | row["PassHours"] = land.PassHours; | ||
1215 | row["PassPrice"] = land.PassPrice; | ||
1216 | row["SnapshotUUID"] = land.SnapshotID.UUID; | ||
1217 | row["UserLocationX"] = land.UserLocation.X; | ||
1218 | row["UserLocationY"] = land.UserLocation.Y; | ||
1219 | row["UserLocationZ"] = land.UserLocation.Z; | ||
1220 | row["UserLookAtX"] = land.UserLookAt.X; | ||
1221 | row["UserLookAtY"] = land.UserLookAt.Y; | ||
1222 | row["UserLookAtZ"] = land.UserLookAt.Z; | ||
1223 | } | ||
1224 | 1047 | ||
1225 | /// <summary> | 1048 | return prim; |
1226 | /// | ||
1227 | /// </summary> | ||
1228 | /// <param name="row"></param> | ||
1229 | /// <param name="entry"></param> | ||
1230 | /// <param name="parcelID"></param> | ||
1231 | private static void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, LLUUID parcelID) | ||
1232 | { | ||
1233 | row["LandUUID"] = parcelID.UUID; | ||
1234 | row["AccessUUID"] = entry.AgentID.UUID; | ||
1235 | row["Flags"] = entry.Flags; | ||
1236 | } | 1049 | } |
1237 | 1050 | ||
1238 | /// <summary> | 1051 | /// <summary> |
1239 | /// | 1052 | /// Builds the prim shape from a datarecord. |
1240 | /// </summary> | 1053 | /// </summary> |
1241 | /// <param name="row"></param> | 1054 | /// <param name="row">The row.</param> |
1242 | /// <returns></returns> | 1055 | /// <returns></returns> |
1243 | private static PrimitiveBaseShape buildShape(DataRow row) | 1056 | private static PrimitiveBaseShape buildShape(DataRow row) |
1244 | { | 1057 | { |
@@ -1269,572 +1082,445 @@ namespace OpenSim.Data.MSSQL | |||
1269 | s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); | 1082 | s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); |
1270 | s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); | 1083 | s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); |
1271 | s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); | 1084 | s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); |
1272 | s.State = Convert.ToByte(row["State"]); | ||
1273 | 1085 | ||
1274 | byte[] textureEntry = (byte[])row["Texture"]; | 1086 | byte[] textureEntry = (byte[])row["Texture"]; |
1275 | s.TextureEntry = textureEntry; | 1087 | s.TextureEntry = textureEntry; |
1276 | 1088 | ||
1277 | s.ExtraParams = (byte[])row["ExtraParams"]; | 1089 | s.ExtraParams = (byte[])row["ExtraParams"]; |
1278 | 1090 | ||
1279 | return s; | 1091 | try |
1280 | } | ||
1281 | |||
1282 | /// <summary> | ||
1283 | /// | ||
1284 | /// </summary> | ||
1285 | /// <param name="row"></param> | ||
1286 | /// <param name="prim"></param> | ||
1287 | private static void fillShapeRow(DataRow row, SceneObjectPart prim) | ||
1288 | { | ||
1289 | PrimitiveBaseShape s = prim.Shape; | ||
1290 | row["UUID"] = prim.UUID; | ||
1291 | // shape is an enum | ||
1292 | row["Shape"] = 0; | ||
1293 | // vectors | ||
1294 | row["ScaleX"] = s.Scale.X; | ||
1295 | row["ScaleY"] = s.Scale.Y; | ||
1296 | row["ScaleZ"] = s.Scale.Z; | ||
1297 | // paths | ||
1298 | row["PCode"] = s.PCode; | ||
1299 | row["PathBegin"] = s.PathBegin; | ||
1300 | row["PathEnd"] = s.PathEnd; | ||
1301 | row["PathScaleX"] = s.PathScaleX; | ||
1302 | row["PathScaleY"] = s.PathScaleY; | ||
1303 | row["PathShearX"] = s.PathShearX; | ||
1304 | row["PathShearY"] = s.PathShearY; | ||
1305 | row["PathSkew"] = s.PathSkew; | ||
1306 | row["PathCurve"] = s.PathCurve; | ||
1307 | row["PathRadiusOffset"] = s.PathRadiusOffset; | ||
1308 | row["PathRevolutions"] = s.PathRevolutions; | ||
1309 | row["PathTaperX"] = s.PathTaperX; | ||
1310 | row["PathTaperY"] = s.PathTaperY; | ||
1311 | row["PathTwist"] = s.PathTwist; | ||
1312 | row["PathTwistBegin"] = s.PathTwistBegin; | ||
1313 | // profile | ||
1314 | row["ProfileBegin"] = s.ProfileBegin; | ||
1315 | row["ProfileEnd"] = s.ProfileEnd; | ||
1316 | row["ProfileCurve"] = s.ProfileCurve; | ||
1317 | row["ProfileHollow"] = s.ProfileHollow; | ||
1318 | row["State"] = s.State; | ||
1319 | row["Texture"] = s.TextureEntry; | ||
1320 | row["ExtraParams"] = s.ExtraParams; | ||
1321 | } | ||
1322 | |||
1323 | /// <summary> | ||
1324 | /// | ||
1325 | /// </summary> | ||
1326 | /// <param name="prim"></param> | ||
1327 | /// <param name="sceneGroupID"></param> | ||
1328 | /// <param name="regionUUID"></param> | ||
1329 | private void addPrim(SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) | ||
1330 | { | ||
1331 | DataTable prims = m_dataSet.Tables["prims"]; | ||
1332 | DataTable shapes = m_dataSet.Tables["primshapes"]; | ||
1333 | |||
1334 | DataRow primRow = prims.Rows.Find(prim.UUID); | ||
1335 | if (primRow == null) | ||
1336 | { | 1092 | { |
1337 | primRow = prims.NewRow(); | 1093 | s.State = Convert.ToByte(row["State"]); |
1338 | fillPrimRow(primRow, prim, sceneGroupID, regionUUID); | ||
1339 | prims.Rows.Add(primRow); | ||
1340 | } | 1094 | } |
1341 | else | 1095 | catch (InvalidCastException) |
1342 | { | 1096 | { |
1343 | fillPrimRow(primRow, prim, sceneGroupID, regionUUID); | ||
1344 | } | 1097 | } |
1345 | 1098 | ||
1346 | DataRow shapeRow = shapes.Rows.Find(prim.UUID); | 1099 | return s; |
1347 | if (shapeRow == null) | ||
1348 | { | ||
1349 | shapeRow = shapes.NewRow(); | ||
1350 | fillShapeRow(shapeRow, prim); | ||
1351 | shapes.Rows.Add(shapeRow); | ||
1352 | } | ||
1353 | else | ||
1354 | { | ||
1355 | fillShapeRow(shapeRow, prim); | ||
1356 | } | ||
1357 | } | 1100 | } |
1358 | 1101 | ||
1359 | /// <summary> | 1102 | /// <summary> |
1360 | /// See <see cref="IRegionDatastore"/> | 1103 | /// Build a prim inventory item from the persisted data. |
1361 | /// </summary> | 1104 | /// </summary> |
1362 | /// <param name="primID"></param> | 1105 | /// <param name="row"></param> |
1363 | /// <param name="items"></param> | 1106 | /// <returns></returns> |
1364 | public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items) | 1107 | private static TaskInventoryItem buildItem(DataRow row) |
1365 | { | 1108 | { |
1366 | m_log.InfoFormat("[REGION DB]: Persisting Prim Inventory with prim ID {0}", primID); | 1109 | TaskInventoryItem taskItem = new TaskInventoryItem(); |
1367 | |||
1368 | // For now, we're just going to crudely remove all the previous inventory items | ||
1369 | // no matter whether they have changed or not, and replace them with the current set. | ||
1370 | lock (m_dataSet) | ||
1371 | { | ||
1372 | RemoveItems(primID); | ||
1373 | 1110 | ||
1374 | // repalce with current inventory details | 1111 | taskItem.ItemID = new LLUUID((String)row["itemID"]); |
1375 | foreach (TaskInventoryItem newItem in items) | 1112 | taskItem.ParentPartID = new LLUUID((String)row["primID"]); |
1376 | { | 1113 | taskItem.AssetID = new LLUUID((String)row["assetID"]); |
1377 | // m_log.InfoFormat( | 1114 | taskItem.ParentID = new LLUUID((String)row["parentFolderID"]); |
1378 | // "[REGION DB]: " + | 1115 | |
1379 | // "Adding item {0}, {1} to prim ID {2}", | 1116 | taskItem.InvType = Convert.ToInt32(row["invType"]); |
1380 | // newItem.Name, newItem.ItemID, newItem.ParentPartID); | 1117 | taskItem.Type = Convert.ToInt32(row["assetType"]); |
1381 | 1118 | ||
1382 | DataRow newItemRow = m_itemsTable.NewRow(); | 1119 | taskItem.Name = (String)row["name"]; |
1383 | fillItemRow(newItemRow, newItem); | 1120 | taskItem.Description = (String)row["description"]; |
1384 | m_itemsTable.Rows.Add(newItemRow); | 1121 | taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); |
1385 | } | 1122 | taskItem.CreatorID = new LLUUID((String)row["creatorID"]); |
1386 | } | 1123 | taskItem.OwnerID = new LLUUID((String)row["ownerID"]); |
1124 | taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]); | ||
1125 | taskItem.GroupID = new LLUUID((String)row["groupID"]); | ||
1126 | |||
1127 | taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); | ||
1128 | taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); | ||
1129 | taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); | ||
1130 | taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); | ||
1131 | taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); | ||
1132 | taskItem.Flags = Convert.ToUInt32(row["flags"]); | ||
1387 | 1133 | ||
1388 | Commit(); | 1134 | return taskItem; |
1389 | } | 1135 | } |
1390 | 1136 | ||
1391 | /*********************************************************************** | 1137 | #endregion |
1392 | * | 1138 | |
1393 | * SQL Statement Creation Functions | 1139 | #region Create parameters methods |
1394 | * | ||
1395 | * These functions create SQL statements for update, insert, and create. | ||
1396 | * They can probably be factored later to have a db independant | ||
1397 | * portion and a db specific portion | ||
1398 | * | ||
1399 | **********************************************************************/ | ||
1400 | 1140 | ||
1401 | /// <summary> | 1141 | /// <summary> |
1402 | /// Create an Insert command | 1142 | /// Creates the prim inventory parameters. |
1403 | /// </summary> | 1143 | /// </summary> |
1404 | /// <param name="table"></param> | 1144 | /// <param name="taskItem">item in inventory.</param> |
1405 | /// <param name="dt"></param> | 1145 | /// <returns></returns> |
1406 | /// <returns>the sql command</returns> | 1146 | private SqlParameter[] CreatePrimInventoryParameters(TaskInventoryItem taskItem) |
1407 | private static SqlCommand createInsertCommand(string table, DataTable dt) | ||
1408 | { | 1147 | { |
1409 | /** | 1148 | SqlParameter[] parameters = new SqlParameter[19]; |
1410 | * This is subtle enough to deserve some commentary. | 1149 | |
1411 | * Instead of doing *lots* and *lots of hardcoded strings | 1150 | parameters[0] = _Database.CreateParameter("itemID", taskItem.ItemID); |
1412 | * for database definitions we'll use the fact that | 1151 | parameters[1] = _Database.CreateParameter("primID", taskItem.ParentPartID); |
1413 | * realistically all insert statements look like "insert | 1152 | parameters[2] = _Database.CreateParameter("assetID", taskItem.AssetID); |
1414 | * into A(b, c) values(:b, :c) on the parameterized query | 1153 | parameters[3] = _Database.CreateParameter("parentFolderID", taskItem.ParentID); |
1415 | * front. If we just have a list of b, c, etc... we can | 1154 | |
1416 | * generate these strings instead of typing them out. | 1155 | parameters[4] = _Database.CreateParameter("invType", taskItem.InvType); |
1417 | */ | 1156 | parameters[5] = _Database.CreateParameter("assetType", taskItem.Type); |
1418 | string[] cols = new string[dt.Columns.Count]; | 1157 | |
1419 | for (int i = 0; i < dt.Columns.Count; i++) | 1158 | parameters[6] = _Database.CreateParameter("name", taskItem.Name); |
1420 | { | 1159 | parameters[7] = _Database.CreateParameter("description", taskItem.Description); |
1421 | DataColumn col = dt.Columns[i]; | 1160 | parameters[8] = _Database.CreateParameter("creationDate", taskItem.CreationDate); |
1422 | cols[i] = col.ColumnName; | 1161 | parameters[9] = _Database.CreateParameter("creatorID", taskItem.CreatorID); |
1423 | } | 1162 | parameters[10] = _Database.CreateParameter("ownerID", taskItem.OwnerID); |
1424 | 1163 | parameters[11] = _Database.CreateParameter("lastOwnerID", taskItem.LastOwnerID); | |
1425 | string sql = "insert into " + table + "("; | 1164 | parameters[12] = _Database.CreateParameter("groupID", taskItem.GroupID); |
1426 | sql += String.Join(", ", cols); | 1165 | parameters[13] = _Database.CreateParameter("nextPermissions", taskItem.NextPermissions); |
1427 | // important, the first ':' needs to be here, the rest get added in the join | 1166 | parameters[14] = _Database.CreateParameter("currentPermissions", taskItem.CurrentPermissions); |
1428 | sql += ") values (@"; | 1167 | parameters[15] = _Database.CreateParameter("basePermissions", taskItem.BasePermissions); |
1429 | sql += String.Join(", @", cols); | 1168 | parameters[16] = _Database.CreateParameter("everyonePermissions", taskItem.EveryonePermissions); |
1430 | sql += ")"; | 1169 | parameters[17] = _Database.CreateParameter("groupPermissions", taskItem.GroupPermissions); |
1431 | SqlCommand cmd = new SqlCommand(sql); | 1170 | parameters[18] = _Database.CreateParameter("flags", taskItem.Flags); |
1432 | 1171 | ||
1433 | // this provides the binding for all our parameters, so | 1172 | return parameters; |
1434 | // much less code than it used to be | ||
1435 | foreach (DataColumn col in dt.Columns) | ||
1436 | { | ||
1437 | cmd.Parameters.Add(createSqlParameter(col.ColumnName, col.DataType)); | ||
1438 | } | ||
1439 | return cmd; | ||
1440 | } | 1173 | } |
1441 | 1174 | ||
1442 | /// <summary> | 1175 | /// <summary> |
1443 | /// Create an update command | 1176 | /// Creates the region setting parameters. |
1444 | /// </summary> | 1177 | /// </summary> |
1445 | /// <param name="table"></param> | 1178 | /// <param name="settings">regionsettings.</param> |
1446 | /// <param name="pk"></param> | 1179 | /// <returns></returns> |
1447 | /// <param name="dt"></param> | 1180 | private SqlParameter[] CreateRegionSettingParameters(RegionSettings settings) |
1448 | /// <returns>the sql command</returns> | ||
1449 | private static SqlCommand createUpdateCommand(string table, string pk, DataTable dt) | ||
1450 | { | 1181 | { |
1451 | string sql = "update " + table + " set "; | 1182 | SqlParameter[] parameters = new SqlParameter[34]; |
1452 | string subsql = String.Empty; | 1183 | |
1453 | foreach (DataColumn col in dt.Columns) | 1184 | parameters[0] = _Database.CreateParameter("regionUUID", settings.RegionUUID); |
1454 | { | 1185 | parameters[1] = _Database.CreateParameter("block_terraform", settings.BlockTerraform); |
1455 | if (subsql.Length > 0) | 1186 | parameters[2] = _Database.CreateParameter("block_fly", settings.BlockFly); |
1456 | { | 1187 | parameters[3] = _Database.CreateParameter("allow_damage", settings.AllowDamage); |
1457 | // a map function would rock so much here | 1188 | parameters[4] = _Database.CreateParameter("restrict_pushing", settings.RestrictPushing); |
1458 | subsql += ", "; | 1189 | parameters[5] = _Database.CreateParameter("allow_land_resell", settings.AllowLandResell); |
1459 | } | 1190 | parameters[6] = _Database.CreateParameter("allow_land_join_divide", settings.AllowLandJoinDivide); |
1460 | subsql += col.ColumnName + "= @" + col.ColumnName; | 1191 | parameters[7] = _Database.CreateParameter("block_show_in_search", settings.BlockShowInSearch); |
1461 | } | 1192 | parameters[8] = _Database.CreateParameter("agent_limit", settings.AgentLimit); |
1462 | sql += subsql; | 1193 | parameters[9] = _Database.CreateParameter("object_bonus", settings.ObjectBonus); |
1463 | sql += " where " + pk; | 1194 | parameters[10] = _Database.CreateParameter("maturity", settings.Maturity); |
1464 | SqlCommand cmd = new SqlCommand(sql); | 1195 | parameters[11] = _Database.CreateParameter("disable_scripts", settings.DisableScripts); |
1465 | 1196 | parameters[12] = _Database.CreateParameter("disable_collisions", settings.DisableCollisions); | |
1466 | // this provides the binding for all our parameters, so | 1197 | parameters[13] = _Database.CreateParameter("disable_physics", settings.DisablePhysics); |
1467 | // much less code than it used to be | 1198 | parameters[14] = _Database.CreateParameter("terrain_texture_1", settings.TerrainTexture1); |
1468 | 1199 | parameters[15] = _Database.CreateParameter("terrain_texture_2", settings.TerrainTexture2); | |
1469 | foreach (DataColumn col in dt.Columns) | 1200 | parameters[16] = _Database.CreateParameter("terrain_texture_3", settings.TerrainTexture3); |
1470 | { | 1201 | parameters[17] = _Database.CreateParameter("terrain_texture_4", settings.TerrainTexture4); |
1471 | cmd.Parameters.Add(createSqlParameter(col.ColumnName, col.DataType)); | 1202 | parameters[18] = _Database.CreateParameter("elevation_1_nw", settings.Elevation1NW); |
1472 | } | 1203 | parameters[19] = _Database.CreateParameter("elevation_2_nw", settings.Elevation2NW); |
1473 | return cmd; | 1204 | parameters[20] = _Database.CreateParameter("elevation_1_ne", settings.Elevation1NE); |
1205 | parameters[21] = _Database.CreateParameter("elevation_2_ne", settings.Elevation2NE); | ||
1206 | parameters[22] = _Database.CreateParameter("elevation_1_se", settings.Elevation1SE); | ||
1207 | parameters[23] = _Database.CreateParameter("elevation_2_se", settings.Elevation2SE); | ||
1208 | parameters[24] = _Database.CreateParameter("elevation_1_sw", settings.Elevation1SW); | ||
1209 | parameters[25] = _Database.CreateParameter("elevation_2_sw", settings.Elevation2SW); | ||
1210 | parameters[26] = _Database.CreateParameter("water_height", settings.WaterHeight); | ||
1211 | parameters[27] = _Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit); | ||
1212 | parameters[28] = _Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit); | ||
1213 | parameters[29] = _Database.CreateParameter("use_estate_sun", settings.UseEstateSun); | ||
1214 | parameters[30] = _Database.CreateParameter("sandbox", settings.Sandbox); | ||
1215 | parameters[31] = _Database.CreateParameter("fixed_sun", settings.FixedSun); | ||
1216 | parameters[32] = _Database.CreateParameter("sun_position", settings.SunPosition); | ||
1217 | parameters[33] = _Database.CreateParameter("covenant", settings.Covenant); | ||
1218 | |||
1219 | return parameters; | ||
1474 | } | 1220 | } |
1475 | 1221 | ||
1476 | /// <summary> | 1222 | /// <summary> |
1477 | /// | 1223 | /// Creates the land parameters. |
1478 | /// </summary> | 1224 | /// </summary> |
1479 | /// <param name="dt"></param> | 1225 | /// <param name="land">land parameters.</param> |
1226 | /// <param name="regionUUID">region UUID.</param> | ||
1480 | /// <returns></returns> | 1227 | /// <returns></returns> |
1481 | private static string defineTable(DataTable dt) | 1228 | private SqlParameter[] CreateLandParameters(LandData land, LLUUID regionUUID) |
1482 | { | 1229 | { |
1483 | string sql = "create table " + dt.TableName + "("; | 1230 | SqlParameter[] parameters = new SqlParameter[32]; |
1484 | string subsql = String.Empty; | ||
1485 | foreach (DataColumn col in dt.Columns) | ||
1486 | { | ||
1487 | if (subsql.Length > 0) | ||
1488 | { | ||
1489 | // a map function would rock so much here | ||
1490 | subsql += ",\n"; | ||
1491 | } | ||
1492 | subsql += col.ColumnName + " " + MSSQLManager.SqlType(col.DataType); | ||
1493 | if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) | ||
1494 | { | ||
1495 | subsql += " primary key"; | ||
1496 | } | ||
1497 | } | ||
1498 | sql += subsql; | ||
1499 | sql += ")"; | ||
1500 | 1231 | ||
1501 | return sql; | 1232 | parameters[0] = _Database.CreateParameter("UUID", land.GlobalID); |
1502 | } | 1233 | parameters[1] = _Database.CreateParameter("RegionUUID", regionUUID); |
1234 | parameters[2] = _Database.CreateParameter("LocalLandID", land.LocalID); | ||
1503 | 1235 | ||
1504 | /*********************************************************************** | 1236 | // Bitmap is a byte[512] |
1505 | * | 1237 | parameters[3] = _Database.CreateParameter("Bitmap", land.Bitmap); |
1506 | * Database Binding functions | 1238 | |
1507 | * | 1239 | parameters[4] = _Database.CreateParameter("Name", land.Name); |
1508 | * These will be db specific due to typing, and minor differences | 1240 | parameters[5] = _Database.CreateParameter("Description", land.Description); |
1509 | * in databases. | 1241 | parameters[6] = _Database.CreateParameter("OwnerUUID", land.OwnerID); |
1510 | * | 1242 | parameters[7] = _Database.CreateParameter("IsGroupOwned", land.IsGroupOwned); |
1511 | **********************************************************************/ | 1243 | parameters[8] = _Database.CreateParameter("Area", land.Area); |
1512 | 1244 | parameters[9] = _Database.CreateParameter("AuctionID", land.AuctionID); //Unemplemented | |
1513 | ///<summary> | 1245 | parameters[10] = _Database.CreateParameter("Category", (int)land.Category); //Enum libsecondlife.Parcel.ParcelCategory |
1514 | /// <para> | 1246 | parameters[11] = _Database.CreateParameter("ClaimDate", land.ClaimDate); |
1515 | /// This is a convenience function that collapses 5 repetitive | 1247 | parameters[12] = _Database.CreateParameter("ClaimPrice", land.ClaimPrice); |
1516 | /// lines for defining SqlParameters to 2 parameters: | 1248 | parameters[13] = _Database.CreateParameter("GroupUUID", land.GroupID); |
1517 | /// column name and database type. | 1249 | parameters[14] = _Database.CreateParameter("SalePrice", land.SalePrice); |
1518 | /// </para> | 1250 | parameters[15] = _Database.CreateParameter("LandStatus", (int)land.Status); //Enum. libsecondlife.Parcel.ParcelStatus |
1519 | /// | 1251 | parameters[16] = _Database.CreateParameter("LandFlags", land.Flags); |
1520 | /// <para> | 1252 | parameters[17] = _Database.CreateParameter("LandingType", land.LandingType); |
1521 | /// It assumes certain conventions like :param as the param | 1253 | parameters[18] = _Database.CreateParameter("MediaAutoScale", land.MediaAutoScale); |
1522 | /// name to replace in parametrized queries, and that source | 1254 | parameters[19] = _Database.CreateParameter("MediaTextureUUID", land.MediaID); |
1523 | /// version is always current version, both of which are fine | 1255 | parameters[20] = _Database.CreateParameter("MediaURL", land.MediaURL); |
1524 | /// for us. | 1256 | parameters[21] = _Database.CreateParameter("MusicURL", land.MusicURL); |
1525 | /// </para> | 1257 | parameters[22] = _Database.CreateParameter("PassHours", land.PassHours); |
1526 | ///</summary> | 1258 | parameters[23] = _Database.CreateParameter("PassPrice", land.PassPrice); |
1527 | ///<returns>a built Sql parameter</returns> | 1259 | parameters[24] = _Database.CreateParameter("SnapshotUUID", land.SnapshotID); |
1528 | private static SqlParameter createSqlParameter(string name, Type type) | 1260 | parameters[25] = _Database.CreateParameter("UserLocationX", land.UserLocation.X); |
1529 | { | 1261 | parameters[26] = _Database.CreateParameter("UserLocationY", land.UserLocation.Y); |
1530 | SqlParameter param = new SqlParameter(); | 1262 | parameters[27] = _Database.CreateParameter("UserLocationZ", land.UserLocation.Z); |
1531 | param.ParameterName = "@" + name; | 1263 | parameters[28] = _Database.CreateParameter("UserLookAtX", land.UserLookAt.X); |
1532 | param.DbType = dbtypeFromType(type); | 1264 | parameters[29] = _Database.CreateParameter("UserLookAtY", land.UserLookAt.Y); |
1533 | param.SourceColumn = name; | 1265 | parameters[30] = _Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z); |
1534 | param.SourceVersion = DataRowVersion.Current; | 1266 | parameters[31] = _Database.CreateParameter("AuthBuyerID", land.AuthBuyerID); |
1535 | return param; | 1267 | |
1268 | return parameters; | ||
1536 | } | 1269 | } |
1537 | 1270 | ||
1538 | /// <summary> | 1271 | /// <summary> |
1539 | /// | 1272 | /// Creates the land access parameters. |
1540 | /// </summary> | 1273 | /// </summary> |
1541 | /// <param name="da"></param> | 1274 | /// <param name="parcelAccessEntry">parcel access entry.</param> |
1542 | /// <param name="conn"></param> | 1275 | /// <param name="parcelID">parcel ID.</param> |
1543 | private void setupPrimCommands(SqlDataAdapter da, SqlConnection conn) | 1276 | /// <returns></returns> |
1277 | private SqlParameter[] CreateLandAccessParameters(ParcelManager.ParcelAccessEntry parcelAccessEntry, LLUUID parcelID) | ||
1544 | { | 1278 | { |
1545 | da.InsertCommand = createInsertCommand("prims", m_dataSet.Tables["prims"]); | 1279 | SqlParameter[] parameters = new SqlParameter[3]; |
1546 | da.InsertCommand.Connection = conn; | ||
1547 | 1280 | ||
1548 | da.UpdateCommand = createUpdateCommand("prims", "UUID=@UUID", m_dataSet.Tables["prims"]); | 1281 | parameters[0] = _Database.CreateParameter("LandUUID", parcelID); |
1549 | da.UpdateCommand.Connection = conn; | 1282 | parameters[1] = _Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID); |
1283 | parameters[2] = _Database.CreateParameter("Flags", parcelAccessEntry.Flags); | ||
1550 | 1284 | ||
1551 | SqlCommand delete = new SqlCommand("delete from prims where UUID = @UUID"); | 1285 | return parameters; |
1552 | delete.Parameters.Add(createSqlParameter("UUID", typeof(String))); | ||
1553 | delete.Connection = conn; | ||
1554 | da.DeleteCommand = delete; | ||
1555 | } | 1286 | } |
1556 | 1287 | ||
1557 | /// <summary> | 1288 | /// <summary> |
1558 | /// | 1289 | /// Fills/Updates the prim datarow. |
1559 | /// </summary> | 1290 | /// </summary> |
1560 | /// <param name="da"></param> | 1291 | /// <param name="row">datarow.</param> |
1561 | /// <param name="conn"></param> | 1292 | /// <param name="prim">prim data.</param> |
1562 | private void SetupItemsCommands(SqlDataAdapter da, SqlConnection conn) | 1293 | /// <param name="sceneGroupID">scenegroup ID.</param> |
1294 | /// <param name="regionUUID">regionUUID.</param> | ||
1295 | private static void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) | ||
1563 | { | 1296 | { |
1564 | da.InsertCommand = createInsertCommand("primitems", m_itemsTable); | 1297 | row["UUID"] = prim.UUID.ToString(); |
1565 | da.InsertCommand.Connection = conn; | 1298 | row["RegionUUID"] = regionUUID.ToString(); |
1299 | row["ParentID"] = prim.ParentID; | ||
1300 | row["CreationDate"] = prim.CreationDate; | ||
1301 | row["Name"] = prim.Name; | ||
1302 | row["SceneGroupID"] = sceneGroupID.ToString(); | ||
1303 | // the UUID of the root part for this SceneObjectGroup | ||
1304 | // various text fields | ||
1305 | row["Text"] = prim.Text; | ||
1306 | row["Description"] = prim.Description; | ||
1307 | row["SitName"] = prim.SitName; | ||
1308 | row["TouchName"] = prim.TouchName; | ||
1309 | // permissions | ||
1310 | row["ObjectFlags"] = prim.ObjectFlags; | ||
1311 | row["CreatorID"] = prim.CreatorID.ToString(); | ||
1312 | row["OwnerID"] = prim.OwnerID.ToString(); | ||
1313 | row["GroupID"] = prim.GroupID.ToString(); | ||
1314 | row["LastOwnerID"] = prim.LastOwnerID.ToString(); | ||
1315 | row["OwnerMask"] = prim.OwnerMask; | ||
1316 | row["NextOwnerMask"] = prim.NextOwnerMask; | ||
1317 | row["GroupMask"] = prim.GroupMask; | ||
1318 | row["EveryoneMask"] = prim.EveryoneMask; | ||
1319 | row["BaseMask"] = prim.BaseMask; | ||
1320 | // vectors | ||
1321 | row["PositionX"] = prim.OffsetPosition.X; | ||
1322 | row["PositionY"] = prim.OffsetPosition.Y; | ||
1323 | row["PositionZ"] = prim.OffsetPosition.Z; | ||
1324 | row["GroupPositionX"] = prim.GroupPosition.X; | ||
1325 | row["GroupPositionY"] = prim.GroupPosition.Y; | ||
1326 | row["GroupPositionZ"] = prim.GroupPosition.Z; | ||
1327 | row["VelocityX"] = prim.Velocity.X; | ||
1328 | row["VelocityY"] = prim.Velocity.Y; | ||
1329 | row["VelocityZ"] = prim.Velocity.Z; | ||
1330 | row["AngularVelocityX"] = prim.AngularVelocity.X; | ||
1331 | row["AngularVelocityY"] = prim.AngularVelocity.Y; | ||
1332 | row["AngularVelocityZ"] = prim.AngularVelocity.Z; | ||
1333 | row["AccelerationX"] = prim.Acceleration.X; | ||
1334 | row["AccelerationY"] = prim.Acceleration.Y; | ||
1335 | row["AccelerationZ"] = prim.Acceleration.Z; | ||
1336 | // quaternions | ||
1337 | row["RotationX"] = prim.RotationOffset.X; | ||
1338 | row["RotationY"] = prim.RotationOffset.Y; | ||
1339 | row["RotationZ"] = prim.RotationOffset.Z; | ||
1340 | row["RotationW"] = prim.RotationOffset.W; | ||
1341 | |||
1342 | // Sit target | ||
1343 | LLVector3 sitTargetPos = prim.SitTargetPositionLL; | ||
1344 | row["SitTargetOffsetX"] = sitTargetPos.X; | ||
1345 | row["SitTargetOffsetY"] = sitTargetPos.Y; | ||
1346 | row["SitTargetOffsetZ"] = sitTargetPos.Z; | ||
1347 | |||
1348 | LLQuaternion sitTargetOrient = prim.SitTargetOrientationLL; | ||
1349 | row["SitTargetOrientW"] = sitTargetOrient.W; | ||
1350 | row["SitTargetOrientX"] = sitTargetOrient.X; | ||
1351 | row["SitTargetOrientY"] = sitTargetOrient.Y; | ||
1352 | row["SitTargetOrientZ"] = sitTargetOrient.Z; | ||
1353 | |||
1354 | row["PayPrice"] = prim.PayPrice[0]; | ||
1355 | row["PayButton1"] = prim.PayPrice[1]; | ||
1356 | row["PayButton2"] = prim.PayPrice[2]; | ||
1357 | row["PayButton3"] = prim.PayPrice[3]; | ||
1358 | row["PayButton4"] = prim.PayPrice[4]; | ||
1359 | |||
1360 | if ((prim.SoundFlags & 1) != 0) // Looped | ||
1361 | { | ||
1362 | row["LoopedSound"] = prim.Sound.ToString(); | ||
1363 | row["LoopedSoundGain"] = prim.SoundGain; | ||
1364 | } | ||
1365 | else | ||
1366 | { | ||
1367 | row["LoopedSound"] = LLUUID.Zero; | ||
1368 | row["LoopedSoundGain"] = 0.0f; | ||
1369 | } | ||
1566 | 1370 | ||
1567 | da.UpdateCommand = createUpdateCommand("primitems", "itemID = @itemID", m_itemsTable); | 1371 | row["TextureAnimation"] = prim.TextureAnimation; |
1568 | da.UpdateCommand.Connection = conn; | ||
1569 | 1372 | ||
1570 | SqlCommand delete = new SqlCommand("delete from primitems where itemID = @itemID"); | 1373 | row["OmegaX"] = prim.RotationalVelocity.X; |
1571 | delete.Parameters.Add(createSqlParameter("itemID", typeof(String))); | 1374 | row["OmegaY"] = prim.RotationalVelocity.Y; |
1572 | delete.Connection = conn; | 1375 | row["OmegaZ"] = prim.RotationalVelocity.Z; |
1573 | da.DeleteCommand = delete; | ||
1574 | } | ||
1575 | 1376 | ||
1576 | /// <summary> | 1377 | row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X; |
1577 | /// | 1378 | row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y; |
1578 | /// </summary> | 1379 | row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z; |
1579 | /// <param name="da"></param> | ||
1580 | /// <param name="conn"></param> | ||
1581 | private void setupTerrainCommands(SqlDataAdapter da, SqlConnection conn) | ||
1582 | { | ||
1583 | da.InsertCommand = createInsertCommand("terrain", m_dataSet.Tables["terrain"]); | ||
1584 | da.InsertCommand.Connection = conn; | ||
1585 | } | ||
1586 | 1380 | ||
1587 | /// <summary> | 1381 | row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X; |
1588 | /// | 1382 | row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y; |
1589 | /// </summary> | 1383 | row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z; |
1590 | /// <param name="da"></param> | ||
1591 | /// <param name="conn"></param> | ||
1592 | private void setupLandCommands(SqlDataAdapter da, SqlConnection conn) | ||
1593 | { | ||
1594 | da.InsertCommand = createInsertCommand("land", m_dataSet.Tables["land"]); | ||
1595 | da.InsertCommand.Connection = conn; | ||
1596 | 1384 | ||
1597 | da.UpdateCommand = createUpdateCommand("land", "UUID=@UUID", m_dataSet.Tables["land"]); | 1385 | if (prim.GetForceMouselook()) |
1598 | da.UpdateCommand.Connection = conn; | 1386 | row["ForceMouselook"] = 1; |
1599 | } | 1387 | else |
1388 | row["ForceMouselook"] = 0; | ||
1600 | 1389 | ||
1601 | /// <summary> | 1390 | row["ScriptAccessPin"] = prim.ScriptAccessPin; |
1602 | /// | ||
1603 | /// </summary> | ||
1604 | /// <param name="da"></param> | ||
1605 | /// <param name="conn"></param> | ||
1606 | private void setupLandAccessCommands(SqlDataAdapter da, SqlConnection conn) | ||
1607 | { | ||
1608 | da.InsertCommand = createInsertCommand("landaccesslist", m_dataSet.Tables["landaccesslist"]); | ||
1609 | da.InsertCommand.Connection = conn; | ||
1610 | } | ||
1611 | 1391 | ||
1612 | /// <summary> | 1392 | if (prim.AllowedDrop) |
1613 | /// | 1393 | row["AllowedDrop"] = 1; |
1614 | /// </summary> | 1394 | else |
1615 | /// <param name="da"></param> | 1395 | row["AllowedDrop"] = 0; |
1616 | /// <param name="conn"></param> | ||
1617 | private void setupShapeCommands(SqlDataAdapter da, SqlConnection conn) | ||
1618 | { | ||
1619 | da.InsertCommand = createInsertCommand("primshapes", m_dataSet.Tables["primshapes"]); | ||
1620 | da.InsertCommand.Connection = conn; | ||
1621 | 1396 | ||
1622 | da.UpdateCommand = createUpdateCommand("primshapes", "UUID=@UUID", m_dataSet.Tables["primshapes"]); | 1397 | if (prim.DIE_AT_EDGE) |
1623 | da.UpdateCommand.Connection = conn; | 1398 | row["DieAtEdge"] = 1; |
1399 | else | ||
1400 | row["DieAtEdge"] = 0; | ||
1624 | 1401 | ||
1625 | SqlCommand delete = new SqlCommand("delete from primshapes where UUID = @UUID"); | 1402 | row["SalePrice"] = prim.SalePrice; |
1626 | delete.Parameters.Add(createSqlParameter("UUID", typeof(String))); | 1403 | row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType); |
1627 | delete.Connection = conn; | ||
1628 | da.DeleteCommand = delete; | ||
1629 | } | 1404 | } |
1630 | 1405 | ||
1631 | /// <summary> | 1406 | /// <summary> |
1632 | /// | 1407 | /// Fills/Updates the shape datarow. |
1633 | /// </summary> | 1408 | /// </summary> |
1634 | /// <param name="conn"></param> | 1409 | /// <param name="row">datarow to fill/update.</param> |
1635 | private static void InitDB(SqlConnection conn) | 1410 | /// <param name="prim">prim shape data.</param> |
1411 | private static void fillShapeRow(DataRow row, SceneObjectPart prim) | ||
1636 | { | 1412 | { |
1637 | string createPrims = defineTable(createPrimTable()); | 1413 | PrimitiveBaseShape s = prim.Shape; |
1638 | string createShapes = defineTable(createShapeTable()); | 1414 | row["UUID"] = prim.UUID.ToString(); |
1639 | string createItems = defineTable(createItemsTable()); | 1415 | // shape is an enum |
1640 | string createTerrain = defineTable(createTerrainTable()); | 1416 | row["Shape"] = 0; |
1641 | string createLand = defineTable(createLandTable()); | 1417 | // vectors |
1642 | string createLandAccessList = defineTable(createLandAccessListTable()); | 1418 | row["ScaleX"] = s.Scale.X; |
1643 | 1419 | row["ScaleY"] = s.Scale.Y; | |
1644 | SqlCommand pcmd = new SqlCommand(createPrims, conn); | 1420 | row["ScaleZ"] = s.Scale.Z; |
1645 | SqlCommand scmd = new SqlCommand(createShapes, conn); | 1421 | // paths |
1646 | SqlCommand icmd = new SqlCommand(createItems, conn); | 1422 | row["PCode"] = s.PCode; |
1647 | SqlCommand tcmd = new SqlCommand(createTerrain, conn); | 1423 | row["PathBegin"] = s.PathBegin; |
1648 | SqlCommand lcmd = new SqlCommand(createLand, conn); | 1424 | row["PathEnd"] = s.PathEnd; |
1649 | SqlCommand lalcmd = new SqlCommand(createLandAccessList, conn); | 1425 | row["PathScaleX"] = s.PathScaleX; |
1650 | 1426 | row["PathScaleY"] = s.PathScaleY; | |
1651 | conn.Open(); | 1427 | row["PathShearX"] = s.PathShearX; |
1652 | try | 1428 | row["PathShearY"] = s.PathShearY; |
1653 | { | 1429 | row["PathSkew"] = s.PathSkew; |
1654 | pcmd.ExecuteNonQuery(); | 1430 | row["PathCurve"] = s.PathCurve; |
1655 | } | 1431 | row["PathRadiusOffset"] = s.PathRadiusOffset; |
1656 | catch (SqlException e) | 1432 | row["PathRevolutions"] = s.PathRevolutions; |
1657 | { | 1433 | row["PathTaperX"] = s.PathTaperX; |
1658 | m_log.WarnFormat("[MSSql]: Primitives Table Already Exists: {0}", e); | 1434 | row["PathTaperY"] = s.PathTaperY; |
1659 | } | 1435 | row["PathTwist"] = s.PathTwist; |
1660 | 1436 | row["PathTwistBegin"] = s.PathTwistBegin; | |
1661 | try | 1437 | // profile |
1662 | { | 1438 | row["ProfileBegin"] = s.ProfileBegin; |
1663 | scmd.ExecuteNonQuery(); | 1439 | row["ProfileEnd"] = s.ProfileEnd; |
1664 | } | 1440 | row["ProfileCurve"] = s.ProfileCurve; |
1665 | catch (SqlException e) | 1441 | row["ProfileHollow"] = s.ProfileHollow; |
1666 | { | 1442 | row["Texture"] = s.TextureEntry; |
1667 | m_log.WarnFormat("[MSSql]: Shapes Table Already Exists: {0}", e); | 1443 | row["ExtraParams"] = s.ExtraParams; |
1668 | } | 1444 | row["State"] = s.State; |
1669 | |||
1670 | try | ||
1671 | { | ||
1672 | icmd.ExecuteNonQuery(); | ||
1673 | } | ||
1674 | catch (SqlException e) | ||
1675 | { | ||
1676 | m_log.WarnFormat("[MSSql]: Items Table Already Exists: {0}", e); | ||
1677 | } | ||
1678 | |||
1679 | try | ||
1680 | { | ||
1681 | tcmd.ExecuteNonQuery(); | ||
1682 | } | ||
1683 | catch (SqlException e) | ||
1684 | { | ||
1685 | m_log.WarnFormat("[MSSql]: Terrain Table Already Exists: {0}", e); | ||
1686 | } | ||
1687 | |||
1688 | try | ||
1689 | { | ||
1690 | lcmd.ExecuteNonQuery(); | ||
1691 | } | ||
1692 | catch (SqlException e) | ||
1693 | { | ||
1694 | m_log.WarnFormat("[MSSql]: Land Table Already Exists: {0}", e); | ||
1695 | } | ||
1696 | |||
1697 | try | ||
1698 | { | ||
1699 | lalcmd.ExecuteNonQuery(); | ||
1700 | } | ||
1701 | catch (SqlException e) | ||
1702 | { | ||
1703 | m_log.WarnFormat("[MSSql]: LandAccessList Table Already Exists: {0}", e); | ||
1704 | } | ||
1705 | conn.Close(); | ||
1706 | } | 1445 | } |
1707 | 1446 | ||
1708 | /// <summary> | 1447 | #endregion |
1709 | /// | 1448 | |
1710 | /// </summary> | 1449 | private void RetrievePrimsDataForRegion(LLUUID regionUUID, LLUUID sceneGroupID, string primID) |
1711 | /// <param name="conn"></param> | ||
1712 | /// <returns></returns> | ||
1713 | private bool TestTables(SqlConnection conn) | ||
1714 | { | 1450 | { |
1715 | SqlCommand primSelectCmd = new SqlCommand(m_primSelect, conn); | 1451 | using (SqlConnection connection = _Database.DatabaseConnection()) |
1716 | SqlDataAdapter pDa = new SqlDataAdapter(primSelectCmd); | ||
1717 | SqlCommand shapeSelectCmd = new SqlCommand(m_shapeSelect, conn); | ||
1718 | SqlDataAdapter sDa = new SqlDataAdapter(shapeSelectCmd); | ||
1719 | SqlCommand itemsSelectCmd = new SqlCommand(m_itemsSelect, conn); | ||
1720 | SqlDataAdapter iDa = new SqlDataAdapter(itemsSelectCmd); | ||
1721 | SqlCommand terrainSelectCmd = new SqlCommand(m_terrainSelect, conn); | ||
1722 | SqlDataAdapter tDa = new SqlDataAdapter(terrainSelectCmd); | ||
1723 | SqlCommand landSelectCmd = new SqlCommand(m_landSelect, conn); | ||
1724 | SqlDataAdapter lDa = new SqlDataAdapter(landSelectCmd); | ||
1725 | SqlCommand landAccessListSelectCmd = new SqlCommand(m_landAccessListSelect, conn); | ||
1726 | SqlDataAdapter lalDa = new SqlDataAdapter(landAccessListSelectCmd); | ||
1727 | |||
1728 | DataSet tmpDS = new DataSet(); | ||
1729 | try | ||
1730 | { | 1452 | { |
1731 | pDa.Fill(tmpDS, "prims"); | 1453 | _PrimDataAdapter.SelectCommand.Connection = connection; |
1732 | sDa.Fill(tmpDS, "primshapes"); | 1454 | _PrimDataAdapter.SelectCommand.Parameters["@RegionUUID"].Value = regionUUID.ToString(); |
1733 | 1455 | if (sceneGroupID != LLUUID.Zero) | |
1734 | iDa.Fill(tmpDS, "primitems"); | 1456 | _PrimDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = sceneGroupID.ToString(); |
1457 | else | ||
1458 | _PrimDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = "%"; | ||
1459 | _PrimDataAdapter.SelectCommand.Parameters["@UUID"].Value = primID; | ||
1735 | 1460 | ||
1736 | tDa.Fill(tmpDS, "terrain"); | 1461 | _PrimDataAdapter.Fill(_PrimsDataSet, "prims"); |
1737 | lDa.Fill(tmpDS, "land"); | ||
1738 | lalDa.Fill(tmpDS, "landaccesslist"); | ||
1739 | } | ||
1740 | catch (SqlException) | ||
1741 | { | ||
1742 | m_log.Info("[REGION DB]: MS Sql Database doesn't exist... creating"); | ||
1743 | InitDB(conn); | ||
1744 | } | ||
1745 | 1462 | ||
1746 | pDa.Fill(tmpDS, "prims"); | 1463 | _ShapeDataAdapter.SelectCommand.Connection = connection; |
1747 | sDa.Fill(tmpDS, "primshapes"); | 1464 | _ShapeDataAdapter.SelectCommand.Parameters["@RegionUUID"].Value = regionUUID.ToString(); |
1465 | if (sceneGroupID != LLUUID.Zero) | ||
1466 | _ShapeDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = sceneGroupID.ToString(); | ||
1467 | else | ||
1468 | _ShapeDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = "%"; | ||
1469 | _ShapeDataAdapter.SelectCommand.Parameters["@UUID"].Value = primID; | ||
1748 | 1470 | ||
1749 | iDa.Fill(tmpDS, "primitems"); | 1471 | _ShapeDataAdapter.Fill(_PrimsDataSet, "primshapes"); |
1750 | 1472 | ||
1751 | tDa.Fill(tmpDS, "terrain"); | 1473 | _ItemsDataAdapter.SelectCommand.Connection = connection; |
1752 | lDa.Fill(tmpDS, "land"); | 1474 | _ItemsDataAdapter.SelectCommand.Parameters["@RegionUUID"].Value = regionUUID.ToString(); |
1753 | lalDa.Fill(tmpDS, "landaccesslist"); | 1475 | if (sceneGroupID != LLUUID.Zero) |
1476 | _ItemsDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = sceneGroupID.ToString(); | ||
1477 | else | ||
1478 | _ItemsDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = "%"; | ||
1479 | _ItemsDataAdapter.SelectCommand.Parameters["@UUID"].Value = primID; | ||
1754 | 1480 | ||
1755 | foreach (DataColumn col in createPrimTable().Columns) | 1481 | _ItemsDataAdapter.Fill(_PrimsDataSet, "primitems"); |
1756 | { | ||
1757 | if (!tmpDS.Tables["prims"].Columns.Contains(col.ColumnName)) | ||
1758 | { | ||
1759 | m_log.Info("[REGION DB]: Missing required column:" + col.ColumnName); | ||
1760 | return false; | ||
1761 | } | ||
1762 | } | 1482 | } |
1483 | } | ||
1763 | 1484 | ||
1764 | foreach (DataColumn col in createShapeTable().Columns) | 1485 | private void CommitDataSet() |
1486 | { | ||
1487 | lock (_PrimsDataSet) | ||
1765 | { | 1488 | { |
1766 | if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName)) | 1489 | using (SqlConnection connection = _Database.DatabaseConnection()) |
1767 | { | 1490 | { |
1768 | m_log.Info("[REGION DB]: Missing required column:" + col.ColumnName); | 1491 | _PrimDataAdapter.InsertCommand.Connection = connection; |
1769 | return false; | 1492 | _PrimDataAdapter.UpdateCommand.Connection = connection; |
1770 | } | 1493 | _PrimDataAdapter.DeleteCommand.Connection = connection; |
1771 | } | ||
1772 | 1494 | ||
1773 | // XXX primitems should probably go here eventually | 1495 | _ShapeDataAdapter.InsertCommand.Connection = connection; |
1496 | _ShapeDataAdapter.UpdateCommand.Connection = connection; | ||
1497 | _ShapeDataAdapter.DeleteCommand.Connection = connection; | ||
1774 | 1498 | ||
1775 | foreach (DataColumn col in createTerrainTable().Columns) | 1499 | _ItemsDataAdapter.InsertCommand.Connection = connection; |
1776 | { | 1500 | _ItemsDataAdapter.UpdateCommand.Connection = connection; |
1777 | if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) | 1501 | _ItemsDataAdapter.DeleteCommand.Connection = connection; |
1778 | { | ||
1779 | m_log.Info("[REGION DB]: Missing require column:" + col.ColumnName); | ||
1780 | return false; | ||
1781 | } | ||
1782 | } | ||
1783 | 1502 | ||
1784 | foreach (DataColumn col in createLandTable().Columns) | 1503 | _PrimDataAdapter.Update(_PrimsDataSet.Tables["prims"]); |
1785 | { | 1504 | _ShapeDataAdapter.Update(_PrimsDataSet.Tables["primshapes"]); |
1786 | if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName)) | 1505 | _ItemsDataAdapter.Update(_PrimsDataSet.Tables["primitems"]); |
1787 | { | ||
1788 | m_log.Info("[REGION DB]: Missing require column:" + col.ColumnName); | ||
1789 | return false; | ||
1790 | } | ||
1791 | } | ||
1792 | 1506 | ||
1793 | foreach (DataColumn col in createLandAccessListTable().Columns) | 1507 | _PrimsDataSet.AcceptChanges(); |
1794 | { | 1508 | |
1795 | if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName)) | 1509 | _PrimsDataSet.Tables["prims"].Clear(); |
1796 | { | 1510 | _PrimsDataSet.Tables["primshapes"].Clear(); |
1797 | m_log.Info("[REGION DB]: Missing require column:" + col.ColumnName); | 1511 | _PrimsDataSet.Tables["primitems"].Clear(); |
1798 | return false; | ||
1799 | } | 1512 | } |
1800 | } | 1513 | } |
1801 | |||
1802 | return true; | ||
1803 | } | 1514 | } |
1804 | 1515 | ||
1805 | /*********************************************************************** | 1516 | private static void SetupCommands(SqlDataAdapter dataAdapter) |
1806 | * | ||
1807 | * Type conversion functions | ||
1808 | * | ||
1809 | **********************************************************************/ | ||
1810 | |||
1811 | /// <summary> | ||
1812 | /// Type conversion function | ||
1813 | /// </summary> | ||
1814 | /// <param name="type">a Type</param> | ||
1815 | /// <returns>a DbType</returns> | ||
1816 | private static DbType dbtypeFromType(Type type) | ||
1817 | { | 1517 | { |
1818 | if (type == typeof(String)) | 1518 | SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter); |
1819 | { | 1519 | |
1820 | return DbType.String; | 1520 | dataAdapter.InsertCommand = commandBuilder.GetInsertCommand(true); |
1821 | } | 1521 | dataAdapter.UpdateCommand = commandBuilder.GetUpdateCommand(true); |
1822 | else if (type == typeof(Int32)) | 1522 | dataAdapter.DeleteCommand = commandBuilder.GetDeleteCommand(true); |
1823 | { | ||
1824 | return DbType.Int32; | ||
1825 | } | ||
1826 | else if (type == typeof(Double)) | ||
1827 | { | ||
1828 | return DbType.Double; | ||
1829 | } | ||
1830 | else if (type == typeof(Byte[])) | ||
1831 | { | ||
1832 | return DbType.Binary; | ||
1833 | } | ||
1834 | else | ||
1835 | { | ||
1836 | return DbType.String; | ||
1837 | } | ||
1838 | } | 1523 | } |
1524 | #endregion | ||
1839 | } | 1525 | } |
1840 | } | 1526 | } |
diff --git a/OpenSim/Data/MSSQL/Resources/001_EstateStore.sql b/OpenSim/Data/MSSQL/Resources/001_EstateStore.sql new file mode 100644 index 0000000..9bb2f75 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/001_EstateStore.sql | |||
@@ -0,0 +1,85 @@ | |||
1 | BEGIN TRANSACTION | ||
2 | |||
3 | CREATE TABLE [dbo].[estate_managers]( | ||
4 | [EstateID] [int] NOT NULL, | ||
5 | [uuid] [varchar](36) NOT NULL, | ||
6 | CONSTRAINT [PK_estate_managers] PRIMARY KEY CLUSTERED | ||
7 | ( | ||
8 | [EstateID] ASC | ||
9 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
10 | ) ON [PRIMARY]; | ||
11 | |||
12 | CREATE TABLE [dbo].[estate_groups]( | ||
13 | [EstateID] [int] NOT NULL, | ||
14 | [uuid] [varchar](36) NOT NULL, | ||
15 | CONSTRAINT [PK_estate_groups] PRIMARY KEY CLUSTERED | ||
16 | ( | ||
17 | [EstateID] ASC | ||
18 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
19 | ) ON [PRIMARY]; | ||
20 | |||
21 | |||
22 | CREATE TABLE [dbo].[estate_users]( | ||
23 | [EstateID] [int] NOT NULL, | ||
24 | [uuid] [varchar](36) NOT NULL, | ||
25 | CONSTRAINT [PK_estate_users] PRIMARY KEY CLUSTERED | ||
26 | ( | ||
27 | [EstateID] ASC | ||
28 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
29 | ) ON [PRIMARY]; | ||
30 | |||
31 | |||
32 | CREATE TABLE [dbo].[estateban]( | ||
33 | [EstateID] [int] NOT NULL, | ||
34 | [bannedUUID] [varchar](36) NOT NULL, | ||
35 | [bannedIp] [varchar](16) NOT NULL, | ||
36 | [bannedIpHostMask] [varchar](16) NOT NULL, | ||
37 | [bannedNameMask] [varchar](64) NULL DEFAULT (NULL), | ||
38 | CONSTRAINT [PK_estateban] PRIMARY KEY CLUSTERED | ||
39 | ( | ||
40 | [EstateID] ASC | ||
41 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
42 | ) ON [PRIMARY]; | ||
43 | |||
44 | CREATE TABLE [dbo].[estate_settings]( | ||
45 | [EstateID] [int] IDENTITY(1,100) NOT NULL, | ||
46 | [EstateName] [varchar](64) NULL DEFAULT (NULL), | ||
47 | [AbuseEmailToEstateOwner] [bit] NOT NULL, | ||
48 | [DenyAnonymous] [bit] NOT NULL, | ||
49 | [ResetHomeOnTeleport] [bit] NOT NULL, | ||
50 | [FixedSun] [bit] NOT NULL, | ||
51 | [DenyTransacted] [bit] NOT NULL, | ||
52 | [BlockDwell] [bit] NOT NULL, | ||
53 | [DenyIdentified] [bit] NOT NULL, | ||
54 | [AllowVoice] [bit] NOT NULL, | ||
55 | [UseGlobalTime] [bit] NOT NULL, | ||
56 | [PricePerMeter] [int] NOT NULL, | ||
57 | [TaxFree] [bit] NOT NULL, | ||
58 | [AllowDirectTeleport] [bit] NOT NULL, | ||
59 | [RedirectGridX] [int] NOT NULL, | ||
60 | [RedirectGridY] [int] NOT NULL, | ||
61 | [ParentEstateID] [int] NOT NULL, | ||
62 | [SunPosition] [float] NOT NULL, | ||
63 | [EstateSkipScripts] [bit] NOT NULL, | ||
64 | [BillableFactor] [float] NOT NULL, | ||
65 | [PublicAccess] [bit] NOT NULL, | ||
66 | [AbuseEmail] [varchar](255) NOT NULL, | ||
67 | [EstateOwner] [varchar](36) NOT NULL, | ||
68 | [DenyMinors] [bit] NOT NULL, | ||
69 | CONSTRAINT [PK_estate_settings] PRIMARY KEY CLUSTERED | ||
70 | ( | ||
71 | [EstateID] ASC | ||
72 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
73 | ) ON [PRIMARY]; | ||
74 | |||
75 | |||
76 | CREATE TABLE [dbo].[estate_map]( | ||
77 | [RegionID] [varchar](36) NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), | ||
78 | [EstateID] [int] NOT NULL, | ||
79 | CONSTRAINT [PK_estate_map] PRIMARY KEY CLUSTERED | ||
80 | ( | ||
81 | [RegionID] ASC | ||
82 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
83 | ) ON [PRIMARY]; | ||
84 | |||
85 | COMMIT \ No newline at end of file | ||
diff --git a/OpenSim/Data/MSSQL/Resources/002_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/002_RegionStore.sql new file mode 100644 index 0000000..1801035 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/002_RegionStore.sql | |||
@@ -0,0 +1,50 @@ | |||
1 | BEGIN TRANSACTION | ||
2 | |||
3 | CREATE TABLE regionban ( | ||
4 | [regionUUID] VARCHAR(36) NOT NULL, | ||
5 | [bannedUUID] VARCHAR(36) NOT NULL, | ||
6 | [bannedIp] VARCHAR(16) NOT NULL, | ||
7 | [bannedIpHostMask] VARCHAR(16) NOT NULL) | ||
8 | |||
9 | create table [dbo].[regionsettings] ( | ||
10 | [regionUUID] [varchar](36) not null, | ||
11 | [block_terraform] [bit] not null, | ||
12 | [block_fly] [bit] not null, | ||
13 | [allow_damage] [bit] not null, | ||
14 | [restrict_pushing] [bit] not null, | ||
15 | [allow_land_resell] [bit] not null, | ||
16 | [allow_land_join_divide] [bit] not null, | ||
17 | [block_show_in_search] [bit] not null, | ||
18 | [agent_limit] [int] not null, | ||
19 | [object_bonus] [float] not null, | ||
20 | [maturity] [int] not null, | ||
21 | [disable_scripts] [bit] not null, | ||
22 | [disable_collisions] [bit] not null, | ||
23 | [disable_physics] [bit] not null, | ||
24 | [terrain_texture_1] [varchar](36) not null, | ||
25 | [terrain_texture_2] [varchar](36) not null, | ||
26 | [terrain_texture_3] [varchar](36) not null, | ||
27 | [terrain_texture_4] [varchar](36) not null, | ||
28 | [elevation_1_nw] [float] not null, | ||
29 | [elevation_2_nw] [float] not null, | ||
30 | [elevation_1_ne] [float] not null, | ||
31 | [elevation_2_ne] [float] not null, | ||
32 | [elevation_1_se] [float] not null, | ||
33 | [elevation_2_se] [float] not null, | ||
34 | [elevation_1_sw] [float] not null, | ||
35 | [elevation_2_sw] [float] not null, | ||
36 | [water_height] [float] not null, | ||
37 | [terrain_raise_limit] [float] not null, | ||
38 | [terrain_lower_limit] [float] not null, | ||
39 | [use_estate_sun] [bit] not null, | ||
40 | [fixed_sun] [bit] not null, | ||
41 | [sun_position] [float] not null, | ||
42 | [covenant] [varchar](36) default NULL, | ||
43 | [Sandbox] [bit] NOT NULL, | ||
44 | PRIMARY KEY CLUSTERED | ||
45 | ( | ||
46 | [regionUUID] ASC | ||
47 | )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||
48 | ) ON [PRIMARY] | ||
49 | |||
50 | COMMIT \ No newline at end of file | ||
diff --git a/OpenSim/Data/MSSQL/Resources/003_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/003_RegionStore.sql new file mode 100644 index 0000000..a8f40c2 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/003_RegionStore.sql | |||
@@ -0,0 +1,67 @@ | |||
1 | BEGIN TRANSACTION | ||
2 | |||
3 | CREATE TABLE dbo.Tmp_prims | ||
4 | ( | ||
5 | UUID varchar(36) NOT NULL, | ||
6 | RegionUUID varchar(36) NULL, | ||
7 | ParentID int NULL, | ||
8 | CreationDate int NULL, | ||
9 | Name varchar(255) NULL, | ||
10 | SceneGroupID varchar(36) NULL, | ||
11 | Text varchar(255) NULL, | ||
12 | Description varchar(255) NULL, | ||
13 | SitName varchar(255) NULL, | ||
14 | TouchName varchar(255) NULL, | ||
15 | ObjectFlags int NULL, | ||
16 | CreatorID varchar(36) NULL, | ||
17 | OwnerID varchar(36) NULL, | ||
18 | GroupID varchar(36) NULL, | ||
19 | LastOwnerID varchar(36) NULL, | ||
20 | OwnerMask int NULL, | ||
21 | NextOwnerMask int NULL, | ||
22 | GroupMask int NULL, | ||
23 | EveryoneMask int NULL, | ||
24 | BaseMask int NULL, | ||
25 | PositionX float(53) NULL, | ||
26 | PositionY float(53) NULL, | ||
27 | PositionZ float(53) NULL, | ||
28 | GroupPositionX float(53) NULL, | ||
29 | GroupPositionY float(53) NULL, | ||
30 | GroupPositionZ float(53) NULL, | ||
31 | VelocityX float(53) NULL, | ||
32 | VelocityY float(53) NULL, | ||
33 | VelocityZ float(53) NULL, | ||
34 | AngularVelocityX float(53) NULL, | ||
35 | AngularVelocityY float(53) NULL, | ||
36 | AngularVelocityZ float(53) NULL, | ||
37 | AccelerationX float(53) NULL, | ||
38 | AccelerationY float(53) NULL, | ||
39 | AccelerationZ float(53) NULL, | ||
40 | RotationX float(53) NULL, | ||
41 | RotationY float(53) NULL, | ||
42 | RotationZ float(53) NULL, | ||
43 | RotationW float(53) NULL, | ||
44 | SitTargetOffsetX float(53) NULL, | ||
45 | SitTargetOffsetY float(53) NULL, | ||
46 | SitTargetOffsetZ float(53) NULL, | ||
47 | SitTargetOrientW float(53) NULL, | ||
48 | SitTargetOrientX float(53) NULL, | ||
49 | SitTargetOrientY float(53) NULL, | ||
50 | SitTargetOrientZ float(53) NULL | ||
51 | ) ON [PRIMARY] | ||
52 | |||
53 | IF EXISTS(SELECT * FROM dbo.prims) | ||
54 | EXEC('INSERT INTO dbo.Tmp_prims (UUID, RegionUUID, ParentID, CreationDate, Name, SceneGroupID, Text, Description, SitName, TouchName, ObjectFlags, CreatorID, OwnerID, GroupID, LastOwnerID, OwnerMask, NextOwnerMask, GroupMask, EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ) | ||
55 | SELECT CONVERT(varchar(36), UUID), CONVERT(varchar(36), RegionUUID), ParentID, CreationDate, Name, CONVERT(varchar(36), SceneGroupID), Text, Description, SitName, TouchName, ObjectFlags, CONVERT(varchar(36), CreatorID), CONVERT(varchar(36), OwnerID), CONVERT(varchar(36), GroupID), CONVERT(varchar(36), LastOwnerID), OwnerMask, NextOwnerMask, GroupMask, EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ FROM dbo.prims WITH (HOLDLOCK TABLOCKX)') | ||
56 | |||
57 | DROP TABLE dbo.prims | ||
58 | |||
59 | EXECUTE sp_rename N'dbo.Tmp_prims', N'prims', 'OBJECT' | ||
60 | |||
61 | ALTER TABLE dbo.prims ADD CONSTRAINT | ||
62 | PK__prims__10566F31 PRIMARY KEY CLUSTERED | ||
63 | ( | ||
64 | UUID | ||
65 | ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] | ||
66 | |||
67 | COMMIT \ No newline at end of file | ||
diff --git a/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql new file mode 100644 index 0000000..4e64901 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql | |||
@@ -0,0 +1,40 @@ | |||
1 | BEGIN TRANSACTION | ||
2 | |||
3 | CREATE TABLE dbo.Tmp_primitems | ||
4 | ( | ||
5 | itemID varchar(36) NOT NULL, | ||
6 | primID varchar(36) NULL, | ||
7 | assetID varchar(36) NULL, | ||
8 | parentFolderID varchar(36) NULL, | ||
9 | invType int NULL, | ||
10 | assetType int NULL, | ||
11 | name varchar(255) NULL, | ||
12 | description varchar(255) NULL, | ||
13 | creationDate varchar(255) NULL, | ||
14 | creatorID varchar(36) NULL, | ||
15 | ownerID varchar(36) NULL, | ||
16 | lastOwnerID varchar(36) NULL, | ||
17 | groupID varchar(36) NULL, | ||
18 | nextPermissions int NULL, | ||
19 | currentPermissions int NULL, | ||
20 | basePermissions int NULL, | ||
21 | everyonePermissions int NULL, | ||
22 | groupPermissions int NULL | ||
23 | ) ON [PRIMARY] | ||
24 | |||
25 | IF EXISTS(SELECT * FROM dbo.primitems) | ||
26 | EXEC('INSERT INTO dbo.Tmp_primitems (itemID, primID, assetID, parentFolderID, invType, assetType, name, description, creationDate, creatorID, ownerID, lastOwnerID, groupID, nextPermissions, currentPermissions, basePermissions, everyonePermissions, groupPermissions) | ||
27 | SELECT CONVERT(varchar(36), itemID), CONVERT(varchar(36), primID), CONVERT(varchar(36), assetID), CONVERT(varchar(36), parentFolderID), invType, assetType, name, description, creationDate, CONVERT(varchar(36), creatorID), CONVERT(varchar(36), ownerID), CONVERT(varchar(36), lastOwnerID), CONVERT(varchar(36), groupID), nextPermissions, currentPermissions, basePermissions, everyonePermissions, groupPermissions') | ||
28 | |||
29 | DROP TABLE dbo.primitems | ||
30 | |||
31 | EXECUTE sp_rename N'dbo.Tmp_primitems', N'primitems', 'OBJECT' | ||
32 | |||
33 | ALTER TABLE dbo.primitems ADD CONSTRAINT | ||
34 | PK__primitems__0A688BB1 PRIMARY KEY CLUSTERED | ||
35 | ( | ||
36 | itemID | ||
37 | ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] | ||
38 | |||
39 | |||
40 | COMMIT | ||
diff --git a/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql new file mode 100644 index 0000000..74e9d85 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql | |||
@@ -0,0 +1,49 @@ | |||
1 | BEGIN TRANSACTION | ||
2 | |||
3 | CREATE TABLE dbo.Tmp_primshapes | ||
4 | ( | ||
5 | UUID varchar(36) NOT NULL, | ||
6 | Shape int NULL, | ||
7 | ScaleX float(53) NULL, | ||
8 | ScaleY float(53) NULL, | ||
9 | ScaleZ float(53) NULL, | ||
10 | PCode int NULL, | ||
11 | PathBegin int NULL, | ||
12 | PathEnd int NULL, | ||
13 | PathScaleX int NULL, | ||
14 | PathScaleY int NULL, | ||
15 | PathShearX int NULL, | ||
16 | PathShearY int NULL, | ||
17 | PathSkew int NULL, | ||
18 | PathCurve int NULL, | ||
19 | PathRadiusOffset int NULL, | ||
20 | PathRevolutions int NULL, | ||
21 | PathTaperX int NULL, | ||
22 | PathTaperY int NULL, | ||
23 | PathTwist int NULL, | ||
24 | PathTwistBegin int NULL, | ||
25 | ProfileBegin int NULL, | ||
26 | ProfileEnd int NULL, | ||
27 | ProfileCurve int NULL, | ||
28 | ProfileHollow int NULL, | ||
29 | State int NULL, | ||
30 | Texture image NULL, | ||
31 | ExtraParams image NULL | ||
32 | ) ON [PRIMARY] | ||
33 | TEXTIMAGE_ON [PRIMARY] | ||
34 | |||
35 | IF EXISTS(SELECT * FROM dbo.primshapes) | ||
36 | EXEC('INSERT INTO dbo.Tmp_primshapes (UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, ProfileEnd, ProfileCurve, ProfileHollow, State, Texture, ExtraParams) | ||
37 | SELECT CONVERT(varchar(36), UUID), Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, ProfileEnd, ProfileCurve, ProfileHollow, State, Texture, ExtraParams FROM dbo.primshapes WITH (HOLDLOCK TABLOCKX)') | ||
38 | |||
39 | DROP TABLE dbo.primshapes | ||
40 | |||
41 | EXECUTE sp_rename N'dbo.Tmp_primshapes', N'primshapes', 'OBJECT' | ||
42 | |||
43 | ALTER TABLE dbo.primshapes ADD CONSTRAINT | ||
44 | PK__primshapes__0880433F PRIMARY KEY CLUSTERED | ||
45 | ( | ||
46 | UUID | ||
47 | ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] | ||
48 | |||
49 | COMMIT \ No newline at end of file | ||
diff --git a/OpenSim/Data/MSSQL/Resources/006_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/006_RegionStore.sql new file mode 100644 index 0000000..0419c0c --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/006_RegionStore.sql | |||
@@ -0,0 +1,36 @@ | |||
1 | BEGIN TRANSACTION | ||
2 | |||
3 | ALTER TABLE prims ADD PayPrice int not null default 0 | ||
4 | ALTER TABLE prims ADD PayButton1 int not null default 0 | ||
5 | ALTER TABLE prims ADD PayButton2 int not null default 0 | ||
6 | ALTER TABLE prims ADD PayButton3 int not null default 0 | ||
7 | ALTER TABLE prims ADD PayButton4 int not null default 0 | ||
8 | ALTER TABLE prims ADD LoopedSound varchar(36) not null default '00000000-0000-0000-0000-000000000000'; | ||
9 | ALTER TABLE prims ADD LoopedSoundGain float not null default 0.0; | ||
10 | ALTER TABLE prims ADD TextureAnimation image | ||
11 | ALTER TABLE prims ADD OmegaX float not null default 0.0 | ||
12 | ALTER TABLE prims ADD OmegaY float not null default 0.0 | ||
13 | ALTER TABLE prims ADD OmegaZ float not null default 0.0 | ||
14 | ALTER TABLE prims ADD CameraEyeOffsetX float not null default 0.0 | ||
15 | ALTER TABLE prims ADD CameraEyeOffsetY float not null default 0.0 | ||
16 | ALTER TABLE prims ADD CameraEyeOffsetZ float not null default 0.0 | ||
17 | ALTER TABLE prims ADD CameraAtOffsetX float not null default 0.0 | ||
18 | ALTER TABLE prims ADD CameraAtOffsetY float not null default 0.0 | ||
19 | ALTER TABLE prims ADD CameraAtOffsetZ float not null default 0.0 | ||
20 | ALTER TABLE prims ADD ForceMouselook tinyint not null default 0 | ||
21 | ALTER TABLE prims ADD ScriptAccessPin int not null default 0 | ||
22 | ALTER TABLE prims ADD AllowedDrop tinyint not null default 0 | ||
23 | ALTER TABLE prims ADD DieAtEdge tinyint not null default 0 | ||
24 | ALTER TABLE prims ADD SalePrice int not null default 10 | ||
25 | ALTER TABLE prims ADD SaleType tinyint not null default 0 | ||
26 | |||
27 | ALTER TABLE primitems add flags integer not null default 0 | ||
28 | |||
29 | ALTER TABLE land ADD AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000' | ||
30 | |||
31 | CREATE index prims_regionuuid on prims(RegionUUID) | ||
32 | CREATE index prims_parentid on prims(ParentID) | ||
33 | |||
34 | CREATE index primitems_primid on primitems(primID) | ||
35 | |||
36 | COMMIT | ||
diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index ecd18ae..8e4cba3 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs | |||
@@ -103,7 +103,7 @@ namespace OpenSim.Data | |||
103 | private void Initialize() | 103 | private void Initialize() |
104 | { | 104 | { |
105 | // clever, eh, we figure out which migrations version we are | 105 | // clever, eh, we figure out which migrations version we are |
106 | int migration_version = FindVersion("migrations"); | 106 | int migration_version = FindVersion(_conn, "migrations"); |
107 | 107 | ||
108 | if (migration_version > 0) | 108 | if (migration_version > 0) |
109 | return; | 109 | return; |
@@ -119,7 +119,7 @@ namespace OpenSim.Data | |||
119 | public void Update() | 119 | public void Update() |
120 | { | 120 | { |
121 | int version = 0; | 121 | int version = 0; |
122 | version = FindVersion(_type); | 122 | version = FindVersion(_conn, _type); |
123 | 123 | ||
124 | SortedList<int, string> migrations = GetMigrationsAfter(version); | 124 | SortedList<int, string> migrations = GetMigrationsAfter(version); |
125 | if (migrations.Count < 1) | 125 | if (migrations.Count < 1) |
@@ -170,7 +170,7 @@ namespace OpenSim.Data | |||
170 | 170 | ||
171 | public int Version | 171 | public int Version |
172 | { | 172 | { |
173 | get { return FindVersion(_type); } | 173 | get { return FindVersion(_conn, _type); } |
174 | set { | 174 | set { |
175 | if (Version < 1) | 175 | if (Version < 1) |
176 | { | 176 | { |
@@ -183,10 +183,10 @@ namespace OpenSim.Data | |||
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | private int FindVersion(string type) | 186 | protected virtual int FindVersion(DbConnection conn, string type) |
187 | { | 187 | { |
188 | int version = 0; | 188 | int version = 0; |
189 | DbCommand cmd = _conn.CreateCommand(); | 189 | DbCommand cmd = conn.CreateCommand(); |
190 | try | 190 | try |
191 | { | 191 | { |
192 | cmd.CommandText = "select version from migrations where name='" + type + "' limit 1"; | 192 | cmd.CommandText = "select version from migrations where name='" + type + "' limit 1"; |