aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MySQL/MySQLRegionData.cs
diff options
context:
space:
mode:
authorMelanie Thielker2008-12-01 18:59:13 +0000
committerMelanie Thielker2008-12-01 18:59:13 +0000
commit5727146d61c4e28876ce236e82cbffb480aee19c (patch)
tree2af2d63cadeb0a84eb0a171b2d2873b1be1e9c27 /OpenSim/Data/MySQL/MySQLRegionData.cs
parent* Unforunately it turns out not to be that simple. Revert the rest of r7560 ... (diff)
downloadopensim-SC-5727146d61c4e28876ce236e82cbffb480aee19c.zip
opensim-SC-5727146d61c4e28876ce236e82cbffb480aee19c.tar.gz
opensim-SC-5727146d61c4e28876ce236e82cbffb480aee19c.tar.bz2
opensim-SC-5727146d61c4e28876ce236e82cbffb480aee19c.tar.xz
More reverts. Revert the MySQL database module. This caused more issues
than it solved by trying to use, and then exhausting, the connection pool
Diffstat (limited to 'OpenSim/Data/MySQL/MySQLRegionData.cs')
-rw-r--r--OpenSim/Data/MySQL/MySQLRegionData.cs987
1 files changed, 513 insertions, 474 deletions
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs
index 3fb0a8a..73605f9 100644
--- a/OpenSim/Data/MySQL/MySQLRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLRegionData.cs
@@ -72,10 +72,73 @@ namespace OpenSim.Data.MySQL
72 cmd.CommandText = "delete from prims, primshapes using prims " + 72 cmd.CommandText = "delete from prims, primshapes using prims " +
73 "left join primshapes on prims.uuid = primshapes.uuid " + 73 "left join primshapes on prims.uuid = primshapes.uuid " +
74 "where PCode = 9 and State <> 0"; 74 "where PCode = 9 and State <> 0";
75 cmd.ExecuteNonQuery(); 75 ExecuteNonQuery(cmd);
76 cmd.Dispose(); 76 cmd.Dispose();
77 }
78
79 private IDataReader ExecuteReader(MySqlCommand c)
80 {
81 IDataReader r = null;
82 bool errorSeen = false;
83
84 while (true)
85 {
86 try
87 {
88 r = c.ExecuteReader();
89 }
90 catch (MySqlException)
91 {
92 System.Threading.Thread.Sleep(500);
93
94 m_Connection.Close();
95 m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
96 m_Connection.Open();
97 c.Connection = m_Connection;
98
99 if (!errorSeen)
100 {
101 errorSeen = true;
102 continue;
103 }
104 throw;
105 }
106
107 break;
108 }
109
110 return r;
111 }
112
113 private void ExecuteNonQuery(MySqlCommand c)
114 {
115 bool errorSeen = false;
116
117 while (true)
118 {
119 try
120 {
121 c.ExecuteNonQuery();
122 }
123 catch (MySqlException)
124 {
125 System.Threading.Thread.Sleep(500);
126
127 m_Connection.Close();
128 m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
129 m_Connection.Open();
130 c.Connection = m_Connection;
77 131
78 m_Connection.Close(); 132 if (!errorSeen)
133 {
134 errorSeen = true;
135 continue;
136 }
137 throw;
138 }
139
140 break;
141 }
79 } 142 }
80 143
81 public void Dispose() {} 144 public void Dispose() {}
@@ -91,116 +154,115 @@ namespace OpenSim.Data.MySQL
91 if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) 154 if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
92 return; 155 return;
93 156
94 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 157 lock (m_Connection)
95 c.Open();
96
97 MySqlCommand cmd = c.CreateCommand();
98
99 foreach (SceneObjectPart prim in obj.Children.Values)
100 { 158 {
101 cmd.Parameters.Clear(); 159 MySqlCommand cmd = m_Connection.CreateCommand();
102
103 cmd.CommandText = "replace into prims ("+
104 "UUID, ParentID, CreationDate, "+
105 "Name, Text, Description, "+
106 "SitName, TouchName, ObjectFlags, "+
107 "OwnerMask, NextOwnerMask, GroupMask, "+
108 "EveryoneMask, BaseMask, PositionX, "+
109 "PositionY, PositionZ, GroupPositionX, "+
110 "GroupPositionY, GroupPositionZ, VelocityX, "+
111 "VelocityY, VelocityZ, AngularVelocityX, "+
112 "AngularVelocityY, AngularVelocityZ, "+
113 "AccelerationX, AccelerationY, "+
114 "AccelerationZ, RotationX, "+
115 "RotationY, RotationZ, "+
116 "RotationW, SitTargetOffsetX, "+
117 "SitTargetOffsetY, SitTargetOffsetZ, "+
118 "SitTargetOrientW, SitTargetOrientX, "+
119 "SitTargetOrientY, SitTargetOrientZ, "+
120 "RegionUUID, CreatorID, "+
121 "OwnerID, GroupID, "+
122 "LastOwnerID, SceneGroupID, "+
123 "PayPrice, PayButton1, "+
124 "PayButton2, PayButton3, "+
125 "PayButton4, LoopedSound, "+
126 "LoopedSoundGain, TextureAnimation, "+
127 "OmegaX, OmegaY, OmegaZ, "+
128 "CameraEyeOffsetX, CameraEyeOffsetY, "+
129 "CameraEyeOffsetZ, CameraAtOffsetX, "+
130 "CameraAtOffsetY, CameraAtOffsetZ, "+
131 "ForceMouselook, ScriptAccessPin, "+
132 "AllowedDrop, DieAtEdge, "+
133 "SalePrice, SaleType, "+
134 "ColorR, ColorG, ColorB, ColorA, "+
135 "ParticleSystem, ClickAction, Material, "+
136 "CollisionSound, CollisionSoundVolume, "+
137 "LinkNumber) values (" + "?UUID, ?ParentID, "+
138 "?CreationDate, ?Name, ?Text, "+
139 "?Description, ?SitName, ?TouchName, "+
140 "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, "+
141 "?GroupMask, ?EveryoneMask, ?BaseMask, "+
142 "?PositionX, ?PositionY, ?PositionZ, "+
143 "?GroupPositionX, ?GroupPositionY, "+
144 "?GroupPositionZ, ?VelocityX, "+
145 "?VelocityY, ?VelocityZ, ?AngularVelocityX, "+
146 "?AngularVelocityY, ?AngularVelocityZ, "+
147 "?AccelerationX, ?AccelerationY, "+
148 "?AccelerationZ, ?RotationX, "+
149 "?RotationY, ?RotationZ, "+
150 "?RotationW, ?SitTargetOffsetX, "+
151 "?SitTargetOffsetY, ?SitTargetOffsetZ, "+
152 "?SitTargetOrientW, ?SitTargetOrientX, "+
153 "?SitTargetOrientY, ?SitTargetOrientZ, "+
154 "?RegionUUID, ?CreatorID, ?OwnerID, "+
155 "?GroupID, ?LastOwnerID, ?SceneGroupID, "+
156 "?PayPrice, ?PayButton1, ?PayButton2, "+
157 "?PayButton3, ?PayButton4, ?LoopedSound, "+
158 "?LoopedSoundGain, ?TextureAnimation, "+
159 "?OmegaX, ?OmegaY, ?OmegaZ, "+
160 "?CameraEyeOffsetX, ?CameraEyeOffsetY, "+
161 "?CameraEyeOffsetZ, ?CameraAtOffsetX, "+
162 "?CameraAtOffsetY, ?CameraAtOffsetZ, "+
163 "?ForceMouselook, ?ScriptAccessPin, "+
164 "?AllowedDrop, ?DieAtEdge, ?SalePrice, "+
165 "?SaleType, ?ColorR, ?ColorG, "+
166 "?ColorB, ?ColorA, ?ParticleSystem, "+
167 "?ClickAction, ?Material, ?CollisionSound, "+
168 "?CollisionSoundVolume, ?LinkNumber)";
169
170 FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
171
172 cmd.ExecuteNonQuery();
173
174 cmd.Parameters.Clear();
175 160
176 cmd.CommandText = "replace into primshapes ("+ 161 foreach (SceneObjectPart prim in obj.Children.Values)
177 "UUID, Shape, ScaleX, ScaleY, "+ 162 {
178 "ScaleZ, PCode, PathBegin, PathEnd, "+ 163 cmd.Parameters.Clear();
179 "PathScaleX, PathScaleY, PathShearX, "+ 164
180 "PathShearY, PathSkew, PathCurve, "+ 165 cmd.CommandText = "replace into prims ("+
181 "PathRadiusOffset, PathRevolutions, "+ 166 "UUID, ParentID, CreationDate, "+
182 "PathTaperX, PathTaperY, PathTwist, "+ 167 "Name, Text, Description, "+
183 "PathTwistBegin, ProfileBegin, ProfileEnd, "+ 168 "SitName, TouchName, ObjectFlags, "+
184 "ProfileCurve, ProfileHollow, Texture, "+ 169 "OwnerMask, NextOwnerMask, GroupMask, "+
185 "ExtraParams, State) values (?UUID, "+ 170 "EveryoneMask, BaseMask, PositionX, "+
186 "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, "+ 171 "PositionY, PositionZ, GroupPositionX, "+
187 "?PCode, ?PathBegin, ?PathEnd, "+ 172 "GroupPositionY, GroupPositionZ, VelocityX, "+
188 "?PathScaleX, ?PathScaleY, "+ 173 "VelocityY, VelocityZ, AngularVelocityX, "+
189 "?PathShearX, ?PathShearY, "+ 174 "AngularVelocityY, AngularVelocityZ, "+
190 "?PathSkew, ?PathCurve, ?PathRadiusOffset, "+ 175 "AccelerationX, AccelerationY, "+
191 "?PathRevolutions, ?PathTaperX, "+ 176 "AccelerationZ, RotationX, "+
192 "?PathTaperY, ?PathTwist, "+ 177 "RotationY, RotationZ, "+
193 "?PathTwistBegin, ?ProfileBegin, "+ 178 "RotationW, SitTargetOffsetX, "+
194 "?ProfileEnd, ?ProfileCurve, "+ 179 "SitTargetOffsetY, SitTargetOffsetZ, "+
195 "?ProfileHollow, ?Texture, ?ExtraParams, "+ 180 "SitTargetOrientW, SitTargetOrientX, "+
196 "?State)"; 181 "SitTargetOrientY, SitTargetOrientZ, "+
197 182 "RegionUUID, CreatorID, "+
198 FillShapeCommand(cmd, prim); 183 "OwnerID, GroupID, "+
199 184 "LastOwnerID, SceneGroupID, "+
200 cmd.ExecuteNonQuery(); 185 "PayPrice, PayButton1, "+
186 "PayButton2, PayButton3, "+
187 "PayButton4, LoopedSound, "+
188 "LoopedSoundGain, TextureAnimation, "+
189 "OmegaX, OmegaY, OmegaZ, "+
190 "CameraEyeOffsetX, CameraEyeOffsetY, "+
191 "CameraEyeOffsetZ, CameraAtOffsetX, "+
192 "CameraAtOffsetY, CameraAtOffsetZ, "+
193 "ForceMouselook, ScriptAccessPin, "+
194 "AllowedDrop, DieAtEdge, "+
195 "SalePrice, SaleType, "+
196 "ColorR, ColorG, ColorB, ColorA, "+
197 "ParticleSystem, ClickAction, Material, "+
198 "CollisionSound, CollisionSoundVolume, "+
199 "LinkNumber) values (" + "?UUID, ?ParentID, "+
200 "?CreationDate, ?Name, ?Text, "+
201 "?Description, ?SitName, ?TouchName, "+
202 "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, "+
203 "?GroupMask, ?EveryoneMask, ?BaseMask, "+
204 "?PositionX, ?PositionY, ?PositionZ, "+
205 "?GroupPositionX, ?GroupPositionY, "+
206 "?GroupPositionZ, ?VelocityX, "+
207 "?VelocityY, ?VelocityZ, ?AngularVelocityX, "+
208 "?AngularVelocityY, ?AngularVelocityZ, "+
209 "?AccelerationX, ?AccelerationY, "+
210 "?AccelerationZ, ?RotationX, "+
211 "?RotationY, ?RotationZ, "+
212 "?RotationW, ?SitTargetOffsetX, "+
213 "?SitTargetOffsetY, ?SitTargetOffsetZ, "+
214 "?SitTargetOrientW, ?SitTargetOrientX, "+
215 "?SitTargetOrientY, ?SitTargetOrientZ, "+
216 "?RegionUUID, ?CreatorID, ?OwnerID, "+
217 "?GroupID, ?LastOwnerID, ?SceneGroupID, "+
218 "?PayPrice, ?PayButton1, ?PayButton2, "+
219 "?PayButton3, ?PayButton4, ?LoopedSound, "+
220 "?LoopedSoundGain, ?TextureAnimation, "+
221 "?OmegaX, ?OmegaY, ?OmegaZ, "+
222 "?CameraEyeOffsetX, ?CameraEyeOffsetY, "+
223 "?CameraEyeOffsetZ, ?CameraAtOffsetX, "+
224 "?CameraAtOffsetY, ?CameraAtOffsetZ, "+
225 "?ForceMouselook, ?ScriptAccessPin, "+
226 "?AllowedDrop, ?DieAtEdge, ?SalePrice, "+
227 "?SaleType, ?ColorR, ?ColorG, "+
228 "?ColorB, ?ColorA, ?ParticleSystem, "+
229 "?ClickAction, ?Material, ?CollisionSound, "+
230 "?CollisionSoundVolume, ?LinkNumber)";
231
232 FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
233
234 ExecuteNonQuery(cmd);
235
236 cmd.Parameters.Clear();
237
238 cmd.CommandText = "replace into primshapes ("+
239 "UUID, Shape, ScaleX, ScaleY, "+
240 "ScaleZ, PCode, PathBegin, PathEnd, "+
241 "PathScaleX, PathScaleY, PathShearX, "+
242 "PathShearY, PathSkew, PathCurve, "+
243 "PathRadiusOffset, PathRevolutions, "+
244 "PathTaperX, PathTaperY, PathTwist, "+
245 "PathTwistBegin, ProfileBegin, ProfileEnd, "+
246 "ProfileCurve, ProfileHollow, Texture, "+
247 "ExtraParams, State) values (?UUID, "+
248 "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, "+
249 "?PCode, ?PathBegin, ?PathEnd, "+
250 "?PathScaleX, ?PathScaleY, "+
251 "?PathShearX, ?PathShearY, "+
252 "?PathSkew, ?PathCurve, ?PathRadiusOffset, "+
253 "?PathRevolutions, ?PathTaperX, "+
254 "?PathTaperY, ?PathTwist, "+
255 "?PathTwistBegin, ?ProfileBegin, "+
256 "?ProfileEnd, ?ProfileCurve, "+
257 "?ProfileHollow, ?Texture, ?ExtraParams, "+
258 "?State)";
259
260 FillShapeCommand(cmd, prim);
261
262 ExecuteNonQuery(cmd);
263 }
264 cmd.Dispose();
201 } 265 }
202 cmd.Dispose();
203 c.Close();
204 } 266 }
205 267
206 public void RemoveObject(UUID obj, UUID regionUUID) 268 public void RemoveObject(UUID obj, UUID regionUUID)
@@ -213,51 +275,43 @@ namespace OpenSim.Data.MySQL
213 // cause the loss of a prim, but is cleaner. 275 // cause the loss of a prim, but is cleaner.
214 // It's also faster because it uses the primary key. 276 // It's also faster because it uses the primary key.
215 // 277 //
216 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 278 lock (m_Connection)
217 c.Open(); 279 {
218 280 MySqlCommand cmd = m_Connection.CreateCommand();
219 MySqlCommand cmd = c.CreateCommand();
220 281
221 cmd.CommandText = "select UUID from prims where "+ 282 cmd.CommandText = "select UUID from prims where "+
222 "SceneGroupID= ?UUID"; 283 "SceneGroupID= ?UUID";
223 284
224 cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(obj)); 285 cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(obj));
225 286
226 List<UUID> uuids = new List<UUID>(); 287 List<UUID> uuids = new List<UUID>();
227 288
228 IDataReader reader = cmd.ExecuteReader(); 289 IDataReader reader = ExecuteReader(cmd);
229 290
230 try 291 try
231 {
232 while(reader.Read())
233 { 292 {
234 uuids.Add(new UUID(reader["UUID"].ToString())); 293 while (reader.Read())
294 {
295 uuids.Add(new UUID(reader["UUID"].ToString()));
296 }
297 }
298 finally
299 {
300 reader.Close();
235 } 301 }
236 }
237 finally
238 {
239 reader.Close();
240 }
241 302
242 cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; 303 foreach (UUID uuid in uuids)
304 RemoveItems(uuid);
243 305
244 cmd.ExecuteNonQuery(); 306 cmd.CommandText = "delete from prims where SceneGroupID= ?UUID";
245 307
246 cmd.CommandText = "delete from primshapes where UUID = ?UUID"; 308 ExecuteNonQuery(cmd);
247 309
248 foreach (UUID uuid in uuids) 310 cmd.CommandText = "delete from primshapes where UUID = ?UUID";
249 {
250 cmd.Parameters.Clear();
251 cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(uuid));
252 311
253 cmd.ExecuteNonQuery(); 312 ExecuteNonQuery(cmd);
313 cmd.Dispose();
254 } 314 }
255
256 cmd.Dispose();
257 c.Close();
258
259 foreach (UUID uuid in uuids)
260 RemoveItems(uuid);
261 } 315 }
262 316
263 /// <summary> 317 /// <summary>
@@ -267,19 +321,18 @@ namespace OpenSim.Data.MySQL
267 /// <param name="uuid">the Item UUID</param> 321 /// <param name="uuid">the Item UUID</param>
268 private void RemoveItems(UUID uuid) 322 private void RemoveItems(UUID uuid)
269 { 323 {
270 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 324 lock (m_Connection)
271 c.Open(); 325 {
272 326 MySqlCommand cmd = m_Connection.CreateCommand();
273 MySqlCommand cmd = c.CreateCommand();
274 327
275 cmd.CommandText = "delete from primitems where " + 328 cmd.CommandText = "delete from primitems where " +
276 "PrimID = ?PrimID"; 329 "PrimID = ?PrimID";
277 330
278 cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); 331 cmd.Parameters.AddWithValue("PrimID", uuid.ToString());
279 332
280 cmd.ExecuteNonQuery(); 333 ExecuteNonQuery(cmd);
281 cmd.Dispose(); 334 cmd.Dispose();
282 c.Close(); 335 }
283 } 336 }
284 337
285 public List<SceneObjectGroup> LoadObjects(UUID regionUUID) 338 public List<SceneObjectGroup> LoadObjects(UUID regionUUID)
@@ -289,72 +342,71 @@ namespace OpenSim.Data.MySQL
289 List<SceneObjectPart> prims = new List<SceneObjectPart>(); 342 List<SceneObjectPart> prims = new List<SceneObjectPart>();
290 SceneObjectGroup grp = null; 343 SceneObjectGroup grp = null;
291 344
292 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 345 lock (m_Connection)
293 c.Open(); 346 {
294 347 MySqlCommand cmd = m_Connection.CreateCommand();
295 MySqlCommand cmd = c.CreateCommand();
296 348
297 cmd.CommandText = "select *, " + 349 cmd.CommandText = "select *, " +
298 "case when prims.UUID = SceneGroupID " + 350 "case when prims.UUID = SceneGroupID " +
299 "then 0 else 1 end as sort from prims " + 351 "then 0 else 1 end as sort from prims " +
300 "left join primshapes on prims.UUID = primshapes.UUID "+ 352 "left join primshapes on prims.UUID = primshapes.UUID "+
301 "where RegionUUID = ?RegionUUID " + 353 "where RegionUUID = ?RegionUUID " +
302 "order by SceneGroupID asc, sort asc, LinkNumber asc"; 354 "order by SceneGroupID asc, sort asc, LinkNumber asc";
303 355
304 cmd.Parameters.AddWithValue("RegionUUID", 356 cmd.Parameters.AddWithValue("RegionUUID",
305 Util.ToRawUuidString(regionUUID)); 357 Util.ToRawUuidString(regionUUID));
306 358
307 IDataReader reader = cmd.ExecuteReader(); 359 IDataReader reader = ExecuteReader(cmd);
308 360
309 try 361 try
310 {
311 while (reader.Read())
312 { 362 {
313 SceneObjectPart prim = BuildPrim(reader); 363 while (reader.Read())
314 if (reader["Shape"] is DBNull) 364 {
315 prim.Shape = PrimitiveBaseShape.Default; 365 SceneObjectPart prim = BuildPrim(reader);
316 else 366 if (reader["Shape"] is DBNull)
317 prim.Shape = BuildShape(reader); 367 prim.Shape = PrimitiveBaseShape.Default;
368 else
369 prim.Shape = BuildShape(reader);
318 370
319 prim.FolderID = prim.UUID; // A relic from when we 371 prim.FolderID = prim.UUID; // A relic from when we
320 // we thought prims contained 372 // we thought prims contained
321 // folder objects. In 373 // folder objects. In
322 // reality, prim == folder 374 // reality, prim == folder
323 prims.Add(prim); 375 prims.Add(prim);
324 376
325 UUID groupID = new UUID(reader["SceneGroupID"].ToString()); 377 UUID groupID = new UUID(reader["SceneGroupID"].ToString());
326 378
327 if (groupID != lastGroupID) // New SOG 379 if (groupID != lastGroupID) // New SOG
328 { 380 {
329 if (grp != null) 381 if (grp != null)
330 objects.Add(grp); 382 objects.Add(grp);
331 383
332 lastGroupID = groupID; 384 lastGroupID = groupID;
333 385
334 grp = new SceneObjectGroup(prim); 386 grp = new SceneObjectGroup(prim);
335 } 387 }
336 else 388 else
337 { 389 {
338 // Black magic to preserve link numbers 390 // Black magic to preserve link numbers
339 // 391 //
340 int link = prim.LinkNum; 392 int link = prim.LinkNum;
341 393
342 grp.AddPart(prim); 394 grp.AddPart(prim);
343 395
344 if (link != 0) 396 if (link != 0)
345 prim.LinkNum = link; 397 prim.LinkNum = link;
398 }
346 } 399 }
347 } 400 }
348 } 401 finally
349 finally 402 {
350 { 403 reader.Close();
351 reader.Close(); 404 }
352 }
353 405
354 if (grp != null) 406 if (grp != null)
355 objects.Add(grp); 407 objects.Add(grp);
356 cmd.Dispose(); 408 cmd.Dispose();
357 c.Close(); 409 }
358 410
359 foreach (SceneObjectPart part in prims) 411 foreach (SceneObjectPart part in prims)
360 LoadItems(part); 412 LoadItems(part);
@@ -370,332 +422,320 @@ namespace OpenSim.Data.MySQL
370 /// <param name="prim">The prim</param> 422 /// <param name="prim">The prim</param>
371 private void LoadItems(SceneObjectPart prim) 423 private void LoadItems(SceneObjectPart prim)
372 { 424 {
373 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 425 lock (m_Connection)
374 c.Open(); 426 {
375 427 MySqlCommand cmd = m_Connection.CreateCommand();
376 MySqlCommand cmd = c.CreateCommand();
377 428
378 cmd.CommandText = "select * from primitems where "+ 429 cmd.CommandText = "select * from primitems where "+
379 "PrimID = ?PrimID"; 430 "PrimID = ?PrimID";
380 431
381 cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); 432 cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString());
382 433
383 IDataReader reader = cmd.ExecuteReader(); 434 IDataReader reader = ExecuteReader(cmd);
384 List<TaskInventoryItem> inventory = 435 List<TaskInventoryItem> inventory =
385 new List<TaskInventoryItem>(); 436 new List<TaskInventoryItem>();
386 437
387 try 438 try
388 {
389 while (reader.Read())
390 { 439 {
391 TaskInventoryItem item = BuildItem(reader); 440 while (reader.Read())
441 {
442 TaskInventoryItem item = BuildItem(reader);
392 443
393 item.ParentID = prim.UUID; // Values in database are 444 item.ParentID = prim.UUID; // Values in database are
394 // often wrong 445 // often wrong
395 inventory.Add(item); 446 inventory.Add(item);
447 }
448 }
449 finally
450 {
451 reader.Close();
396 } 452 }
397 }
398 finally
399 {
400 reader.Close();
401 }
402 453
403 cmd.Dispose(); 454 cmd.Dispose();
404 c.Close(); 455 prim.Inventory.RestoreInventoryItems(inventory);
405 prim.Inventory.RestoreInventoryItems(inventory); 456 }
406 } 457 }
407 458
408 public void StoreTerrain(double[,] ter, UUID regionID) 459 public void StoreTerrain(double[,] ter, UUID regionID)
409 { 460 {
410 m_log.Info("[REGION DB]: Storing terrain"); 461 m_log.Info("[REGION DB]: Storing terrain");
411 462
412 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 463 lock (m_Connection)
413 c.Open(); 464 {
414 465 MySqlCommand cmd = m_Connection.CreateCommand();
415 MySqlCommand cmd = c.CreateCommand(); 466
416 467 cmd.CommandText = "delete from terrain where " +
417 cmd.CommandText = "delete from terrain where " + 468 "RegionUUID = ?RegionUUID";
418 "RegionUUID = ?RegionUUID"; 469 cmd.Parameters.AddWithValue("RegionUUID",
419 cmd.Parameters.AddWithValue("RegionUUID", 470 Util.ToRawUuidString(regionID));
420 Util.ToRawUuidString(regionID)); 471
421 472 ExecuteNonQuery(cmd);
422 cmd.ExecuteNonQuery(); 473
423 474 cmd.CommandText = "insert into terrain (RegionUUID, " +
424 cmd.CommandText = "insert into terrain (RegionUUID, " + 475 "Revision, Heightfield) values (?RegionUUID, " +
425 "Revision, Heightfield) values (?RegionUUID, " + 476 "1, ?Heightfield)";
426 "1, ?Heightfield)"; 477
427 478 cmd.Parameters.AddWithValue("Heightfield",
428 cmd.Parameters.AddWithValue("Heightfield", 479 SerializeTerrain(ter));
429 SerializeTerrain(ter)); 480
430 481 ExecuteNonQuery(cmd);
431 cmd.ExecuteNonQuery(); 482 cmd.Dispose();
432 cmd.Dispose(); 483 }
433 c.Close();
434 } 484 }
435 485
436 public double[,] LoadTerrain(UUID regionID) 486 public double[,] LoadTerrain(UUID regionID)
437 { 487 {
438 double[,] terrain = new double[256,256]; 488 double[,] terrain = null;
439 terrain.Initialize();
440
441 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
442 c.Open();
443 489
444 MySqlCommand cmd = c.CreateCommand(); 490 lock (m_Connection)
445 491 {
446 cmd.CommandText = "select RegionUUID, Revision, Heightfield " + 492 MySqlCommand cmd = m_Connection.CreateCommand();
447 "from terrain where RegionUUID = ?RegionUUID "+ 493 cmd.CommandText = "select RegionUUID, Revision, Heightfield " +
448 "order by Revision desc limit 1"; 494 "from terrain where RegionUUID = ?RegionUUID "+
449 cmd.Parameters.AddWithValue("RegionUUID", Util.ToRawUuidString(regionID)); 495 "order by Revision desc limit 1";
496 cmd.Parameters.AddWithValue("RegionUUID", Util.ToRawUuidString(regionID));
450 497
451 IDataReader reader = cmd.ExecuteReader(); 498 IDataReader reader = ExecuteReader(cmd);
452 499
453 try 500 try
454 {
455 while (reader.Read())
456 { 501 {
457 MemoryStream mstr = new MemoryStream((byte[]) reader["Heightfield"]); 502 while (reader.Read())
458 int rev = 0;
459
460 BinaryReader br = new BinaryReader(mstr);
461 for (int x = 0; x < 256; x++)
462 { 503 {
463 for (int y = 0; y < 256; y++) 504 terrain = new double[256,256];
505 terrain.Initialize();
506
507 MemoryStream mstr = new MemoryStream((byte[]) reader["Heightfield"]);
508 int rev = 0;
509
510 BinaryReader br = new BinaryReader(mstr);
511 for (int x = 0; x < 256; x++)
464 { 512 {
465 terrain[x, y] = br.ReadDouble(); 513 for (int y = 0; y < 256; y++)
514 {
515 terrain[x, y] = br.ReadDouble();
516 }
517 rev = Convert.ToInt32(reader["Revision"]);
466 } 518 }
467 rev = Convert.ToInt32(reader["Revision"]); 519 m_log.InfoFormat("[REGION DB]: Loaded terrain " +
520 "revision r{0}", rev);
468 } 521 }
469 m_log.InfoFormat("[REGION DB]: Loaded terrain " + 522 }
470 "revision r{0}", rev); 523 finally
471 524 {
472 reader.Close(); 525 reader.Close();
473 cmd.Dispose();
474 c.Close();
475 return terrain;
476 } 526 }
527 cmd.Dispose();
477 } 528 }
478 catch (Exception)
479 {
480 }
481 reader.Close();
482 cmd.Dispose();
483 c.Close();
484 529
485 return null; 530 return null;
486 } 531 }
487 532
488 public void RemoveLandObject(UUID globalID) 533 public void RemoveLandObject(UUID globalID)
489 { 534 {
490 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 535 lock (m_Connection)
491 c.Open(); 536 {
492 537 MySqlCommand cmd = m_Connection.CreateCommand();
493 MySqlCommand cmd = c.CreateCommand();
494 538
495 cmd.CommandText = "delete from land where UUID = ?UUID"; 539 cmd.CommandText = "delete from land where UUID = ?UUID";
496 540
497 cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(globalID)); 541 cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(globalID));
498 542
499 cmd.ExecuteNonQuery(); 543 ExecuteNonQuery(cmd);
500 cmd.Dispose(); 544 cmd.Dispose();
501 c.Close(); 545 }
502 } 546 }
503 547
504 public void StoreLandObject(ILandObject parcel) 548 public void StoreLandObject(ILandObject parcel)
505 { 549 {
506 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 550 lock (m_Connection)
507 c.Open();
508
509 MySqlCommand cmd = c.CreateCommand();
510
511 cmd.CommandText = "replace into land (UUID, RegionUUID, " +
512 "LocalLandID, Bitmap, Name, Description, " +
513 "OwnerUUID, IsGroupOwned, Area, AuctionID, " +
514 "Category, ClaimDate, ClaimPrice, GroupUUID, " +
515 "SalePrice, LandStatus, LandFlags, LandingType, " +
516 "MediaAutoScale, MediaTextureUUID, MediaURL, " +
517 "MusicURL, PassHours, PassPrice, SnapshotUUID, " +
518 "UserLocationX, UserLocationY, UserLocationZ, " +
519 "UserLookAtX, UserLookAtY, UserLookAtZ, " +
520 "AuthbuyerID, OtherCleanTime, Dwell) values (" +
521 "?UUID, ?RegionUUID, " +
522 "?LocalLandID, ?Bitmap, ?Name, ?Description, " +
523 "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
524 "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " +
525 "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " +
526 "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " +
527 "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " +
528 "?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
529 "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
530 "?AuthbuyerID, ?OtherCleanTime, ?Dwell)";
531
532 FillLandCommand(cmd, parcel.landData, parcel.regionUUID);
533
534 cmd.ExecuteNonQuery();
535
536 cmd.CommandText = "delete from landaccesslist where " +
537 "LandUUID = ?UUID";
538
539 cmd.ExecuteNonQuery();
540
541 cmd.Parameters.Clear();
542 cmd.CommandText = "insert into landaccesslist (LandUUID, " +
543 "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " +
544 "?Flags)";
545
546 foreach (ParcelManager.ParcelAccessEntry entry in
547 parcel.landData.ParcelAccessList)
548 { 551 {
549 FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID); 552 MySqlCommand cmd = m_Connection.CreateCommand();
550 cmd.ExecuteNonQuery(); 553
554 cmd.CommandText = "replace into land (UUID, RegionUUID, " +
555 "LocalLandID, Bitmap, Name, Description, " +
556 "OwnerUUID, IsGroupOwned, Area, AuctionID, " +
557 "Category, ClaimDate, ClaimPrice, GroupUUID, " +
558 "SalePrice, LandStatus, LandFlags, LandingType, " +
559 "MediaAutoScale, MediaTextureUUID, MediaURL, " +
560 "MusicURL, PassHours, PassPrice, SnapshotUUID, " +
561 "UserLocationX, UserLocationY, UserLocationZ, " +
562 "UserLookAtX, UserLookAtY, UserLookAtZ, " +
563 "AuthbuyerID, OtherCleanTime, Dwell) values (" +
564 "?UUID, ?RegionUUID, " +
565 "?LocalLandID, ?Bitmap, ?Name, ?Description, " +
566 "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
567 "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " +
568 "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " +
569 "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " +
570 "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " +
571 "?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
572 "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
573 "?AuthbuyerID, ?OtherCleanTime, ?Dwell)";
574
575 FillLandCommand(cmd, parcel.landData, parcel.regionUUID);
576
577 ExecuteNonQuery(cmd);
578
579 cmd.CommandText = "delete from landaccesslist where " +
580 "LandUUID = ?UUID";
581
582 ExecuteNonQuery(cmd);
583
551 cmd.Parameters.Clear(); 584 cmd.Parameters.Clear();
585 cmd.CommandText = "insert into landaccesslist (LandUUID, " +
586 "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " +
587 "?Flags)";
588
589 foreach (ParcelManager.ParcelAccessEntry entry in
590 parcel.landData.ParcelAccessList)
591 {
592 FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID);
593 ExecuteNonQuery(cmd);
594 cmd.Parameters.Clear();
595 }
596 cmd.Dispose();
552 } 597 }
553 cmd.Dispose();
554 c.Close();
555 } 598 }
556 599
557 public RegionSettings LoadRegionSettings(UUID regionUUID) 600 public RegionSettings LoadRegionSettings(UUID regionUUID)
558 { 601 {
559 RegionSettings rs = null; 602 RegionSettings rs = null;
560 603
561 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 604 lock (m_Connection)
562 c.Open(); 605 {
563 606 MySqlCommand cmd = m_Connection.CreateCommand();
564 MySqlCommand cmd = c.CreateCommand();
565 607
566 cmd.CommandText = "select * from regionsettings where " + 608 cmd.CommandText = "select * from regionsettings where " +
567 "regionUUID = ?RegionUUID"; 609 "regionUUID = ?RegionUUID";
568 cmd.Parameters.AddWithValue("regionUUID", regionUUID); 610 cmd.Parameters.AddWithValue("regionUUID", regionUUID);
569 611
570 IDataReader reader = cmd.ExecuteReader(); 612 IDataReader reader = ExecuteReader(cmd);
571 613
572 try 614 try
573 {
574 if (reader.Read())
575 { 615 {
576 rs = BuildRegionSettings(reader); 616 if (reader.Read())
577 rs.OnSave += StoreRegionSettings; 617 {
618 rs = BuildRegionSettings(reader);
619 rs.OnSave += StoreRegionSettings;
620 }
621 else
622 {
623 rs = new RegionSettings();
624 rs.RegionUUID = regionUUID;
625 rs.OnSave += StoreRegionSettings;
626
627 StoreRegionSettings(rs);
628 }
578 } 629 }
579 else 630 finally
580 { 631 {
581 rs = new RegionSettings(); 632 reader.Close();
582 rs.RegionUUID = regionUUID;
583 rs.OnSave += StoreRegionSettings;
584
585 StoreRegionSettings(rs);
586 } 633 }
634 cmd.Dispose();
587 } 635 }
588 finally
589 {
590 reader.Close();
591 }
592 cmd.Dispose();
593 c.Close();
594 636
595 return rs; 637 return rs;
596 } 638 }
597 639
598 public void StoreRegionSettings(RegionSettings rs) 640 public void StoreRegionSettings(RegionSettings rs)
599 { 641 {
600 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 642 lock (m_Connection)
601 c.Open(); 643 {
602 644 MySqlCommand cmd = m_Connection.CreateCommand();
603 MySqlCommand cmd = c.CreateCommand(); 645
604 646 cmd.CommandText = "replace into regionsettings (regionUUID, " +
605 cmd.CommandText = "replace into regionsettings (regionUUID, " + 647 "block_terraform, block_fly, allow_damage, " +
606 "block_terraform, block_fly, allow_damage, " + 648 "restrict_pushing, allow_land_resell, " +
607 "restrict_pushing, allow_land_resell, " + 649 "allow_land_join_divide, block_show_in_search, " +
608 "allow_land_join_divide, block_show_in_search, " + 650 "agent_limit, object_bonus, maturity, " +
609 "agent_limit, object_bonus, maturity, " + 651 "disable_scripts, disable_collisions, " +
610 "disable_scripts, disable_collisions, " + 652 "disable_physics, terrain_texture_1, " +
611 "disable_physics, terrain_texture_1, " + 653 "terrain_texture_2, terrain_texture_3, " +
612 "terrain_texture_2, terrain_texture_3, " + 654 "terrain_texture_4, elevation_1_nw, " +
613 "terrain_texture_4, elevation_1_nw, " + 655 "elevation_2_nw, elevation_1_ne, " +
614 "elevation_2_nw, elevation_1_ne, " + 656 "elevation_2_ne, elevation_1_se, "+
615 "elevation_2_ne, elevation_1_se, "+ 657 "elevation_2_se, elevation_1_sw, "+
616 "elevation_2_se, elevation_1_sw, "+ 658 "elevation_2_sw, water_height, " +
617 "elevation_2_sw, water_height, " + 659 "terrain_raise_limit, terrain_lower_limit, " +
618 "terrain_raise_limit, terrain_lower_limit, " + 660 "use_estate_sun, fixed_sun, sun_position, " +
619 "use_estate_sun, fixed_sun, sun_position, " + 661 "covenant, Sandbox, sunvectorx, sunvectory, " +
620 "covenant, Sandbox, sunvectorx, sunvectory, " + 662 "sunvectorz) values ( ?RegionUUID, ?BlockTerraform, " +
621 "sunvectorz) values ( ?RegionUUID, ?BlockTerraform, " + 663 "?BlockFly, ?AllowDamage, ?RestrictPushing, " +
622 "?BlockFly, ?AllowDamage, ?RestrictPushing, " + 664 "?AllowLandResell, ?AllowLandJoinDivide, " +
623 "?AllowLandResell, ?AllowLandJoinDivide, " + 665 "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
624 "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + 666 "?Maturity, ?DisableScripts, ?DisableCollisions, " +
625 "?Maturity, ?DisableScripts, ?DisableCollisions, " + 667 "?DisablePhysics, ?TerrainTexture1, " +
626 "?DisablePhysics, ?TerrainTexture1, " + 668 "?TerrainTexture2, ?TerrainTexture3, " +
627 "?TerrainTexture2, ?TerrainTexture3, " + 669 "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
628 "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + 670 "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
629 "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + 671 "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
630 "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + 672 "?WaterHeight, ?TerrainRaiseLimit, " +
631 "?WaterHeight, ?TerrainRaiseLimit, " + 673 "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
632 "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + 674 "?SunPosition, ?Covenant, ?Sandbox, " +
633 "?SunPosition, ?Covenant, ?Sandbox, " + 675 "?SunVectorX, ?SunVectorY, ?SunVectorZ)";
634 "?SunVectorX, ?SunVectorY, ?SunVectorZ)"; 676
635 677 FillRegionSettingsCommand(cmd, rs);
636 FillRegionSettingsCommand(cmd, rs); 678
637 679 ExecuteNonQuery(cmd);
638 cmd.ExecuteNonQuery(); 680 cmd.Dispose();
639 cmd.Dispose(); 681 }
640 c.Close();
641 } 682 }
642 683
643 public List<LandData> LoadLandObjects(UUID regionUUID) 684 public List<LandData> LoadLandObjects(UUID regionUUID)
644 { 685 {
645 List<LandData> landData = new List<LandData>(); 686 List<LandData> landData = new List<LandData>();
646 687
647 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone(); 688 lock (m_Connection)
648 c.Open();
649
650 MySqlCommand cmd = c.CreateCommand();
651
652 cmd.CommandText = "select * from land where " +
653 "RegionUUID = ?RegionUUID";
654
655 cmd.Parameters.AddWithValue("RegionUUID",
656 Util.ToRawUuidString(regionUUID));
657
658 IDataReader reader = cmd.ExecuteReader();
659
660 try
661 {
662 while (reader.Read())
663 {
664 LandData newLand = BuildLandData(reader);
665 landData.Add(newLand);
666 }
667 }
668 finally
669 { 689 {
670 reader.Close(); 690 MySqlCommand cmd = m_Connection.CreateCommand();
671 }
672 691
673 foreach (LandData land in landData) 692 cmd.CommandText = "select * from land where " +
674 { 693 "RegionUUID = ?RegionUUID";
675 cmd.Parameters.Clear();
676 694
677 cmd.CommandText = "select * from landaccesslist " + 695 cmd.Parameters.AddWithValue("RegionUUID",
678 "where LandUUID = ?LandUUID"; 696 Util.ToRawUuidString(regionUUID));
679 697
680 cmd.Parameters.AddWithValue("LandUUID", 698 IDataReader reader = ExecuteReader(cmd);
681 Util.ToRawUuidString(land.GlobalID));
682
683 reader = cmd.ExecuteReader();
684 699
685 try 700 try
686 { 701 {
687 while (reader.Read()) 702 while (reader.Read())
688 { 703 {
689 land.ParcelAccessList.Add(BuildLandAccessData(reader)); 704 LandData newLand = BuildLandData(reader);
705 landData.Add(newLand);
690 } 706 }
691 } 707 }
692 finally 708 finally
693 { 709 {
694 reader.Close(); 710 reader.Close();
695 } 711 }
712
713 foreach (LandData land in landData)
714 {
715 cmd.Parameters.Clear();
716
717 cmd.CommandText = "select * from landaccesslist " +
718 "where LandUUID = ?LandUUID";
719
720 cmd.Parameters.AddWithValue("LandUUID",
721 Util.ToRawUuidString(land.GlobalID));
722
723 reader = ExecuteReader(cmd);
724
725 try
726 {
727 while (reader.Read())
728 {
729 land.ParcelAccessList.Add(BuildLandAccessData(reader));
730 }
731 }
732 finally
733 {
734 reader.Close();
735 }
736 }
737 cmd.Dispose();
696 } 738 }
697 cmd.Dispose();
698 c.Close();
699 739
700 return landData; 740 return landData;
701 } 741 }
@@ -1379,42 +1419,41 @@ byte[] textureEntry = (byte[]) row["Texture"];
1379 1419
1380 public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) 1420 public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
1381 { 1421 {
1382 RemoveItems(primID); 1422 lock (m_Connection)
1383
1384 MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
1385 c.Open();
1386
1387 MySqlCommand cmd = c.CreateCommand();
1388
1389 if (items.Count == 0)
1390 return;
1391
1392 cmd.CommandText = "insert into primitems ("+
1393 "invType, assetType, name, "+
1394 "description, creationDate, nextPermissions, "+
1395 "currentPermissions, basePermissions, "+
1396 "everyonePermissions, groupPermissions, "+
1397 "flags, itemID, primID, assetID, "+
1398 "parentFolderID, creatorID, ownerID, "+
1399 "groupID, lastOwnerID) values (?invType, "+
1400 "?assetType, ?name, ?description, "+
1401 "?creationDate, ?nextPermissions, "+
1402 "?currentPermissions, ?basePermissions, "+
1403 "?everyonePermissions, ?groupPermissions, "+
1404 "?flags, ?itemID, ?primID, ?assetID, "+
1405 "?parentFolderID, ?creatorID, ?ownerID, "+
1406 "?groupID, ?lastOwnerID)";
1407
1408 foreach (TaskInventoryItem item in items)
1409 { 1423 {
1410 cmd.Parameters.Clear(); 1424 RemoveItems(primID);
1425
1426 MySqlCommand cmd = m_Connection.CreateCommand();
1427
1428 if (items.Count == 0)
1429 return;
1430
1431 cmd.CommandText = "insert into primitems ("+
1432 "invType, assetType, name, "+
1433 "description, creationDate, nextPermissions, "+
1434 "currentPermissions, basePermissions, "+
1435 "everyonePermissions, groupPermissions, "+
1436 "flags, itemID, primID, assetID, "+
1437 "parentFolderID, creatorID, ownerID, "+
1438 "groupID, lastOwnerID) values (?invType, "+
1439 "?assetType, ?name, ?description, "+
1440 "?creationDate, ?nextPermissions, "+
1441 "?currentPermissions, ?basePermissions, "+
1442 "?everyonePermissions, ?groupPermissions, "+
1443 "?flags, ?itemID, ?primID, ?assetID, "+
1444 "?parentFolderID, ?creatorID, ?ownerID, "+
1445 "?groupID, ?lastOwnerID)";
1446
1447 foreach (TaskInventoryItem item in items)
1448 {
1449 cmd.Parameters.Clear();
1411 1450
1412 FillItemCommand(cmd, item); 1451 FillItemCommand(cmd, item);
1413 1452
1414 cmd.ExecuteNonQuery(); 1453 ExecuteNonQuery(cmd);
1454 }
1455 cmd.Dispose();
1415 } 1456 }
1416 cmd.Dispose();
1417 c.Close();
1418 } 1457 }
1419 } 1458 }
1420} 1459}