From f6251ce810e0bebe68d08a8e4b20a9dfc3fe1af6 Mon Sep 17 00:00:00 2001
From: Kunnis
Date: Sat, 15 Aug 2009 06:08:36 -0500
Subject: * Modified SQLite/SQLiteInventoryStore.cs to not throw if the
 inventory row does not exist, to match the mysql behavior. * Modified
 SQLite/SQLiteRegionData.cs to only persist temporary items following the same
 rules mysql uses. * Added another ignore to the inventory test that was
 missing. * Added a few more ignores to the RegionTest that the first version
 of my test were missing. * Added ignoring the root Folder ID, which is set by
 the inventory system. * Added several improvements to the
 PropertyCompareConstraint: Protection against infinite loops, added
 IComparable<T> (for UUID) and moved IComparable before the property matching.
 * Fixed a bug where I was saving the inside of the ignore expression instead
 of the outside of it.

---
 OpenSim/Data/SQLite/SQLiteInventoryStore.cs     |   3 +-
 OpenSim/Data/SQLite/SQLiteRegionData.cs         |  29 ++--
 OpenSim/Data/Tests/BasicInventoryTest.cs        |   1 +
 OpenSim/Data/Tests/BasicRegionTest.cs           |   4 +-
 OpenSim/Data/Tests/BasicUserTest.cs             |   1 +
 OpenSim/Data/Tests/PropertyCompareConstraint.cs | 180 ++++++++++++++++++------
 6 files changed, 154 insertions(+), 64 deletions(-)

(limited to 'OpenSim/Data')

diff --git a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs
index 97c40ba..557dec7 100644
--- a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs
+++ b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs
@@ -301,7 +301,8 @@ namespace OpenSim.Data.SQLite
                 DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
 
                 inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString());
-                inventoryRow["version"] = (int)inventoryRow["version"] + 1;
+                if(inventoryRow != null) //MySQL doesn't throw an exception here, so sqlite shouldn't either.
+                    inventoryRow["version"] = (int)inventoryRow["version"] + 1;
 
                 invFoldersDa.Update(ds, "inventoryfolders");
             }
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index d2548c2..0259ac5 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -307,26 +307,21 @@ namespace OpenSim.Data.SQLite
         /// <param name="regionUUID">the region UUID</param>
         public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
         {
+            uint flags = obj.RootPart.GetEffectiveObjectFlags();
+
+            // Eligibility check
+            //
+            if ((flags & (uint)PrimFlags.Temporary) != 0)
+                return;
+            if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
+                return;
+
             lock (ds)
             {
                 foreach (SceneObjectPart prim in obj.Children.Values)
                 {
-                    if ((prim.GetEffectiveObjectFlags() & (uint)PrimFlags.Temporary) == 0
-                        && (prim.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) == 0)
-                    {
-                        m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
-                        addPrim(prim, obj.UUID, regionUUID);
-                    }
-                    else if (prim.Stopped)
-                    {
-                        //m_log.Info("[DATASTORE]: " +
-                                                 //"Adding stopped obj: " + obj.UUID + " to region: " + regionUUID);
-                        //addPrim(prim, obj.UUID.ToString(), regionUUID.ToString());
-                    }
-                    else
-                    {
-                        // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID);
-                    }
+                    m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
+                    addPrim(prim, obj.UUID, regionUUID);
                 }
             }
 
@@ -1130,7 +1125,7 @@ namespace OpenSim.Data.SQLite
             // explicit conversion of integers is required, which sort
             // of sucks.  No idea if there is a shortcut here or not.
             prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
-            prim.Name = (String) row["Name"];
+            prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"];
             // various text fields
             prim.Text = (String) row["Text"];
             prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
diff --git a/OpenSim/Data/Tests/BasicInventoryTest.cs b/OpenSim/Data/Tests/BasicInventoryTest.cs
index 3c33bb4..967c6e7 100644
--- a/OpenSim/Data/Tests/BasicInventoryTest.cs
+++ b/OpenSim/Data/Tests/BasicInventoryTest.cs
@@ -266,6 +266,7 @@ namespace OpenSim.Data.Tests
             InventoryItemBase actual = db.getInventoryItem(item1);
             Assert.That(actual, Constraints.PropertyCompareConstraint(expected)
                 .IgnoreProperty(x=>x.InvType)
+                .IgnoreProperty(x=>x.CreatorIdAsUuid)
                 .IgnoreProperty(x=>x.Description)
                 .IgnoreProperty(x=>x.CreatorId));
         }
diff --git a/OpenSim/Data/Tests/BasicRegionTest.cs b/OpenSim/Data/Tests/BasicRegionTest.cs
index a746ef0..8373922 100644
--- a/OpenSim/Data/Tests/BasicRegionTest.cs
+++ b/OpenSim/Data/Tests/BasicRegionTest.cs
@@ -576,8 +576,10 @@ namespace OpenSim.Data.Tests
                 .IgnoreProperty(x=>x.HasGroupChanged)
                 .IgnoreProperty(x=>x.IsSelected)
                 .IgnoreProperty(x=>x.RegionHandle)
+                .IgnoreProperty(x=>x.RegionUUID)
                 .IgnoreProperty(x=>x.Scene)
-                .IgnoreProperty(x=>x.RootPart.InventorySerial));
+                .IgnoreProperty(x=>x.Children)
+                .IgnoreProperty(x=>x.RootPart));
         }
         
         [Test]
diff --git a/OpenSim/Data/Tests/BasicUserTest.cs b/OpenSim/Data/Tests/BasicUserTest.cs
index 21d1a7e..a3c125d 100644
--- a/OpenSim/Data/Tests/BasicUserTest.cs
+++ b/OpenSim/Data/Tests/BasicUserTest.cs
@@ -403,6 +403,7 @@ namespace OpenSim.Data.Tests
             Assert.That(u1a, Constraints.PropertyCompareConstraint(u)
                 .IgnoreProperty(x=>x.HomeRegionX)
                 .IgnoreProperty(x=>x.HomeRegionY)
+                .IgnoreProperty(x=>x.RootInventoryFolderID)
                 );
         }
         
diff --git a/OpenSim/Data/Tests/PropertyCompareConstraint.cs b/OpenSim/Data/Tests/PropertyCompareConstraint.cs
index 063267b..5f53725 100644
--- a/OpenSim/Data/Tests/PropertyCompareConstraint.cs
+++ b/OpenSim/Data/Tests/PropertyCompareConstraint.cs
@@ -69,6 +69,15 @@ namespace OpenSim.Data.Tests
 
         private bool ObjectCompare(object expected, object actual, Stack<string> propertyNames)
         {
+            //prevent loops...
+            if(propertyNames.Count > 50)
+            {
+                failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
+                failingActual = actual;
+                failingExpected = expected;
+                return false;
+            }
+
             if (actual.GetType() != expected.GetType())
             {
                 propertyNames.Push("GetType()");
@@ -122,6 +131,60 @@ namespace OpenSim.Data.Tests
                 return true;
             }
 
+            IComparable comp = actual as IComparable;
+            if (comp != null)
+            {
+                if (comp.CompareTo(expected) != 0)
+                {
+                    failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
+                    failingActual = actual;
+                    failingExpected = expected;
+                    return false;
+                }
+                return true;
+            }
+
+            //Now try the much more annoying IComparable<T>
+            Type icomparableInterface = actual.GetType().GetInterface("IComparable`1");
+            if (icomparableInterface != null)
+            {
+                int result = (int)icomparableInterface.GetMethod("CompareTo").Invoke(actual, new[] { expected });
+                if (result != 0)
+                {
+                    failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
+                    failingActual = actual;
+                    failingExpected = expected;
+                    return false;
+                }
+                return true;
+            }
+
+            IEnumerable arr = actual as IEnumerable;
+            if (arr != null)
+            {
+                List<object> actualList = arr.Cast<object>().ToList();
+                List<object> expectedList = ((IEnumerable)expected).Cast<object>().ToList();
+                if (actualList.Count != expectedList.Count)
+                {
+                    propertyNames.Push("Count");
+                    failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
+                    failingActual = actualList.Count;
+                    failingExpected = expectedList.Count;
+                    propertyNames.Pop();
+                    return false;
+                }
+                //actualList and expectedList should be the same size.
+                for (int i = 0; i < actualList.Count; i++)
+                {
+                    propertyNames.Push("[" + i + "]");
+                    if (!ObjectCompare(expectedList[i], actualList[i], propertyNames))
+                        return false;
+                    propertyNames.Pop();
+                }
+                //Everything seems okay...
+                return true;
+            }
+
             //Skip static properties.  I had a nasty problem comparing colors because of all of the public static colors.
             PropertyInfo[] properties = expected.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
             foreach (var property in properties)
@@ -147,41 +210,6 @@ namespace OpenSim.Data.Tests
                     return false;
                 }
 
-                IComparable comp = actualValue as IComparable;
-                if (comp != null)
-                {
-                    if (comp.CompareTo(expectedValue) != 0)
-                    {
-                        propertyNames.Push(property.Name);
-                        failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
-                        propertyNames.Pop();
-                        failingActual = actualValue;
-                        failingExpected = expectedValue;
-                        return false;
-                    }
-                    continue;
-                }
-
-                IEnumerable arr = actualValue as IEnumerable;
-                if (arr != null)
-                {
-                    List<object> actualList = arr.Cast<object>().ToList();
-                    List<object> expectedList = ((IEnumerable)expectedValue).Cast<object>().ToList();
-                    if (actualList.Count != expectedList.Count)
-                    {
-                        propertyNames.Push(property.Name);
-                        propertyNames.Push("Count");
-                        failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
-                        failingActual = actualList.Count;
-                        failingExpected = expectedList.Count;
-                        propertyNames.Pop();
-                        propertyNames.Pop();
-                    }
-                    //Todo: A value-wise comparison of all of the values.
-                    //Everything seems okay...
-                    continue;
-                }
-
                 propertyNames.Push(property.Name);
                 if (!ObjectCompare(expectedValue, actualValue, propertyNames))
                     return false;
@@ -223,15 +251,7 @@ namespace OpenSim.Data.Tests
             {
                 //If the inside of the lambda is the access to x, we've hit the end of the chain.
                 //   We should track by the fully scoped parameter name, but this is the first rev of doing this.
-                if (((MemberExpression)express).Expression is ParameterExpression)
-                {
-                    ignores.Add(((MemberExpression)express).Member.Name);
-                }
-                else
-                {
-                    //Otherwise there could be more parameters inside...
-                    PullApartExpression(((MemberExpression)express).Expression);
-                }
+                ignores.Add(((MemberExpression)express).Member.Name);
             }
         }
     }
@@ -270,7 +290,7 @@ namespace OpenSim.Data.Tests
         {
             HasInt actual = new HasInt { TheValue = 5 };
             HasInt expected = new HasInt { TheValue = 4 };
-            var constraint = Constraints.PropertyCompareConstraint(expected).IgnoreProperty(x=>x.TheValue);
+            var constraint = Constraints.PropertyCompareConstraint(expected).IgnoreProperty(x => x.TheValue);
 
             Assert.That(constraint.Matches(actual), Is.True);
         }
@@ -312,6 +332,28 @@ namespace OpenSim.Data.Tests
         }
 
         [Test]
+        public void UUIDShouldMatch()
+        {
+            UUID uuid1 = UUID.Random();
+            UUID uuid2 = UUID.Parse(uuid1.ToString());
+
+            var constraint = Constraints.PropertyCompareConstraint(uuid1);
+
+            Assert.That(constraint.Matches(uuid2), Is.True);
+        }
+
+        [Test]
+        public void UUIDShouldNotMatch()
+        {
+            UUID uuid1 = UUID.Random();
+            UUID uuid2 = UUID.Random();
+
+            var constraint = Constraints.PropertyCompareConstraint(uuid1);
+
+            Assert.That(constraint.Matches(uuid2), Is.False);
+        }
+
+        [Test]
         public void TestColors()
         {
             Color actual = Color.Red;
@@ -321,5 +363,53 @@ namespace OpenSim.Data.Tests
 
             Assert.That(constraint.Matches(actual), Is.True);
         }
+
+        [Test]
+        public void ShouldCompareLists()
+        {
+            List<int> expected = new List<int> { 1, 2, 3 };
+            List<int> actual = new List<int> { 1, 2, 3 };
+
+            var constraint = Constraints.PropertyCompareConstraint(expected);
+            Assert.That(constraint.Matches(actual), Is.True);
+        }
+
+
+        [Test]
+        public void ShouldFailToCompareListsThatAreDifferent()
+        {
+            List<int> expected = new List<int> { 1, 2, 3 };
+            List<int> actual = new List<int> { 1, 2, 4 };
+
+            var constraint = Constraints.PropertyCompareConstraint(expected);
+            Assert.That(constraint.Matches(actual), Is.False);
+        }
+
+        [Test]
+        public void ShouldFailToCompareListsThatAreDifferentLengths()
+        {
+            List<int> expected = new List<int> { 1, 2, 3 };
+            List<int> actual = new List<int> { 1, 2 };
+
+            var constraint = Constraints.PropertyCompareConstraint(expected);
+            Assert.That(constraint.Matches(actual), Is.False);
+        }
+
+        public class Recursive
+        {
+            public Recursive Other { get; set; }
+        }
+
+        [Test]
+        public void ErrorsOutOnRecursive()
+        {
+            Recursive parent = new Recursive();
+            Recursive child = new Recursive();
+            parent.Other = child;
+            child.Other = parent;
+
+            var constraint = Constraints.PropertyCompareConstraint(child);
+            Assert.That(constraint.Matches(child), Is.False);
+        }
     }
 }
\ No newline at end of file
-- 
cgit v1.1