Realm configuration specifying settings that affect the Realm's behavior.
Its main role is generating a canonical path from whatever absolute, relative subdirectory, or just filename the user supplies.
Inheritance: RealmConfigurationBase
Ejemplo n.º 1
0
        public void CanOverrideConfigurationFilename()
        {
            // Arrange
            var config = new RealmConfiguration();
            var config2 = config.ConfigWithPath("fred.realm");

            // Assert
            Assert.That(config2.DatabasePath, Is.StringEnding("fred.realm"));
        }
Ejemplo n.º 2
0
        public void TriggerMigrationBySchemaVersion()
        {
            // Arrange
            var config1 = new RealmConfiguration("ChangingVersion.realm");
            Realm.DeleteRealm(config1);  // ensure start clean
            var realm1 = Realm.GetInstance(config1);

            // new database doesn't push back a version number
            Assert.That(config1.SchemaVersion, Is.EqualTo(0));
            realm1.Dispose();

            // Act
            var config2 = config1.ConfigWithPath("ChangingVersion.realm");
            config2.SchemaVersion = 99;
            Realm realm2 = null;  // should be updated by DoesNotThrow

            // Assert
            Assert.DoesNotThrow(() => realm2 = Realm.GetInstance(config2)); // same path, different version, should auto-migrate quietly
            Assert.That(realm2.Config.SchemaVersion, Is.EqualTo(99));
            realm2.Dispose();
        }
Ejemplo n.º 3
0
        private static bool MigrationCallback(IntPtr oldRealmPtr, IntPtr newRealmPtr, Native.Schema oldSchema, ulong schemaVersion, IntPtr managedMigrationHandle)
        {
            var migrationHandle = GCHandle.FromIntPtr(managedMigrationHandle);
            var migration       = (Migration)migrationHandle.Target;

            var oldRealmHandle   = new UnownedRealmHandle(oldRealmPtr);
            var oldConfiguration = new RealmConfiguration(migration._configuration.DatabasePath)
            {
                SchemaVersion = schemaVersion, IsReadOnly = true
            };
            var oldRealm = new Realm(oldRealmHandle, oldConfiguration, RealmSchema.CreateFromObjectStoreSchema(oldSchema));

            var newRealmHandle = new UnownedRealmHandle(newRealmPtr);
            var newRealm       = new Realm(newRealmHandle, migration._configuration, migration._schema);

            var result = migration.Execute(oldRealm, newRealm);

            migrationHandle.Free();

            return(result);
        }
Ejemplo n.º 4
0
        internal static Realm GetInstance(RealmConfiguration config, RealmSchema schema)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            if (schema == null)
            {
                if (config.ObjectClasses != null)
                {
                    schema = RealmSchema.CreateSchemaForClasses(config.ObjectClasses);
                }
                else
                {
                    schema = RealmSchema.Default;
                }
            }

            return(config.CreateRealm(schema));
        }
Ejemplo n.º 5
0
        public void TriggerMigrationBySchemaEditing()
        {
            // NOTE to regnerate the bundled database go edit the schema in Person.cs and comment/uncomment ExtraToTriggerMigration
            // running in between and saving a copy with the added field
            // this should never be needed as this test just needs the Realm to need migrating
            TestHelpers.CopyBundledDatabaseToDocuments(
                "ForMigrationsToCopyAndMigrate.realm", "NeedsMigrating.realm");

            var triggersSchemaFieldValue = string.Empty;

            var configuration = new RealmConfiguration("NeedsMigrating.realm");
            configuration.SchemaVersion = 100;
            configuration.MigrationCallback = (migration, oldSchemaVersion) =>
            {
                Assert.That(oldSchemaVersion, Is.EqualTo(99));

                var oldPeople = migration.OldRealm.All("Person");
                var newPeople = migration.NewRealm.All<Person>();

                Assert.That(newPeople.Count(), Is.EqualTo(oldPeople.Count()));

                for (var i = 0; i < newPeople.Count(); i++)
                {
                    var oldPerson = oldPeople.ElementAt(i);
                    var newPerson = newPeople.ElementAt(i);

                    Assert.That(newPerson.LastName, Is.Not.EqualTo(oldPerson.TriggersSchema));
                    newPerson.LastName = triggersSchemaFieldValue = oldPerson.TriggersSchema;
                }
            };

            using (var realm = Realm.GetInstance(configuration))
            {
                var person = realm.All<Person>().Single();
                Assert.That(person.LastName, Is.EqualTo(triggersSchemaFieldValue));
            }
        }
Ejemplo n.º 6
0
        public override void SetUp()
        {
            _configuration = new RealmConfiguration { ObjectClasses = new[] { typeof(DynamicOwner), typeof(DynamicDog) } };
            if (_mode == DynamicTestObjectType.DynamicRealmObject)
            {
                _configuration.Dynamic = true;
            }

            base.SetUp();

            using (var trans = _realm.BeginWrite())
            {
                var o1 = _realm.CreateObject("DynamicOwner");
                o1.Name = "Tim";

                var d1 = _realm.CreateObject("DynamicDog");
                d1.Name = "Bilbo Fleabaggins";
                d1.Color = "Black";
                o1.TopDog = d1;  // set a one-one relationship
                o1.Dogs.Add(d1);

                var d2 = _realm.CreateObject("DynamicDog");
                d2.Name = "Earl Yippington III";
                d2.Color = "White";
                o1.Dogs.Add(d2);

                // lonely people and dogs
                var o2 = _realm.CreateObject("DynamicOwner");
                o2.Name = "Dani";  // the dog-less

                var d3 = _realm.CreateObject("DynamicDog");  // will remain unassigned
                d3.Name = "Maggie Mongrel";
                d3.Color = "Grey";

                trans.Commit();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Clone method allowing you to override or customise the current path.
        /// </summary>
        /// <returns>An object with a fully-specified, canonical path.</returns>
        /// <param name="newConfigPath">Path to the realm, must be a valid full path for the current platform, relative subdir, or just filename.</param>
        public RealmConfiguration ConfigWithPath(string newConfigPath)
        {
            RealmConfiguration ret = (RealmConfiguration)MemberwiseClone();
            string             candidatePath; // may need canonicalising

            if (!string.IsNullOrEmpty(newConfigPath))
            {
                if (Path.IsPathRooted(newConfigPath))
                {
                    candidatePath = newConfigPath;
                }
                else    // append a relative path, maybe just a relative subdir needing filename
                {
                    var usWithoutFile = Path.GetDirectoryName(DatabasePath);
                    if (newConfigPath[newConfigPath.Length - 1] == Path.DirectorySeparatorChar) // ends with separator
                    {
                        newConfigPath = Path.Combine(newConfigPath, DefaultRealmName);          // add filename to relative subdir
                    }
                    candidatePath = Path.Combine(usWithoutFile, newConfigPath);
                }
                ret.DatabasePath = Path.GetFullPath(candidatePath);  // canonical version, removing embedded ../ and other relative artifacts
            }
            return(ret);
        }
Ejemplo n.º 8
0
        public void AbleToReopenEncryptedWithSameKey()
        {
            ReliesOnEncryption();

            // Arrange
            var config = new RealmConfiguration("AbleToReopenEncryptedWithSameKey.realm");
            Realm.DeleteRealm(config);  // ensure guarded from prev tests
            var answerKey = new byte[64];
            answerKey[0] = 42;
            config.EncryptionKey = answerKey;
            var openedWithKey = Realm.GetInstance(config);
            openedWithKey.Dispose();

            var config2 = new RealmConfiguration("AbleToReopenEncryptedWithSameKey.realm");
            var answerKey2 = new byte[64];
            answerKey2[0] = 42;
            config2.EncryptionKey = answerKey2;

            // Assert
            Assert.DoesNotThrow(() =>
            {
                using (Realm.GetInstance(config2))
                {
                }
            });
        }
Ejemplo n.º 9
0
        public void ValidEncryptionKeyAccepted()
        {
            ReliesOnEncryption();

            // Arrange
            var config = new RealmConfiguration("ValidEncryptionKeyAcceoted.realm");
            var goldilocksKey = new byte[64];

            // Assert
            Assert.DoesNotThrow(() => config.EncryptionKey = goldilocksKey);
            Assert.DoesNotThrow(() => config.EncryptionKey = null);
        }
Ejemplo n.º 10
0
        private static bool MigrationCallback(IntPtr oldRealmPtr, IntPtr newRealmPtr, Native.Schema oldSchema, ulong schemaVersion, IntPtr managedMigrationHandle)
        {
            var migrationHandle = GCHandle.FromIntPtr(managedMigrationHandle);
            var migration = (Migration)migrationHandle.Target;

            // the realms here are owned by Object Store so we should do nothing to clean them up
            var oldRealmHandle = new UnownedRealmHandle();
            var newRealmHandle = new UnownedRealmHandle();

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
            }
            finally
            {
                oldRealmHandle.SetHandle(oldRealmPtr);
                newRealmHandle.SetHandle(newRealmPtr);
            }

            var oldConfiguration = new RealmConfiguration(migration._configuration.DatabasePath) { SchemaVersion = schemaVersion, IsReadOnly = true };
            var oldRealm = new Realm(oldRealmHandle, oldConfiguration, RealmSchema.CreateFromObjectStoreSchema(oldSchema));

            var newRealm = new Realm(newRealmHandle, migration._configuration, migration._schema);

            var result = migration.Execute(oldRealm, newRealm);
            migrationHandle.Free();

            return result;
        }
Ejemplo n.º 11
0
        public void ReadOnlyRealmsWillNotAutoMigrate()
        {
            // Arrange
            var config = new RealmConfiguration("WillBeReadonly.realm");
            Realm.DeleteRealm(config);  // ensure start clean
            config.IsReadOnly = true;
            config.SchemaVersion = 42;
            TestHelpers.CopyBundledDatabaseToDocuments(
                "ForMigrationsToCopyAndMigrate.realm", "WillBeReadonly.realm");

            // Assert
            Assert.Throws<RealmMigrationNeededException>(() =>
            {
                Realm.GetInstance(config);
            });
        }
Ejemplo n.º 12
0
 public void TearDown()
 {
     Realm.DeleteRealm(RealmConfiguration.DefaultConfiguration);
     var uniqueConfig = new RealmConfiguration(SpecialRealmName);  // for when need 2 realms or want to not use default
     Realm.DeleteRealm(uniqueConfig);
 }
Ejemplo n.º 13
0
        public static Realm GetInstance(RealmConfiguration config = null)
        {
            config = config ?? RealmConfiguration.DefaultConfiguration;

            // TODO cache these initializers but note complications with ObjectClasses
            var schemaInitializer = new SchemaInitializerHandle();

            if (config.ObjectClasses == null)
            {
                foreach (var realmObjectClass in RealmObjectClasses)
                {
                    var objectSchemaHandle = GenerateObjectSchema(realmObjectClass);
                    NativeSchema.initializer_add_object_schema(schemaInitializer, objectSchemaHandle);
                }
            }
            else
            {
                foreach (var selectedRealmObjectClass in config.ObjectClasses)
                {
                    if (selectedRealmObjectClass.BaseType != typeof(RealmObject))
                    {
                        throw new ArgumentException($"The class {selectedRealmObjectClass.FullName} must descend directly from RealmObject");
                    }

                    Debug.Assert(RealmObjectClasses.Contains(selectedRealmObjectClass));  // user-specified class must have been picked up by our static ctor
                    var objectSchemaHandle = GenerateObjectSchema(selectedRealmObjectClass);
                    NativeSchema.initializer_add_object_schema(schemaInitializer, objectSchemaHandle);
                }
            }

            var schemaHandle = new SchemaHandle(schemaInitializer);

            var srHandle = new SharedRealmHandle();

            var    readOnly     = MarshalHelpers.BoolToIntPtr(config.ReadOnly);
            var    durability   = MarshalHelpers.BoolToIntPtr(false);
            var    databasePath = config.DatabasePath;
            IntPtr srPtr        = IntPtr.Zero;

            try {
                srPtr = NativeSharedRealm.open(schemaHandle,
                                               databasePath, (IntPtr)databasePath.Length,
                                               readOnly, durability,
                                               config.EncryptionKey,
                                               config.SchemaVersion);
            } catch (RealmMigrationNeededException) {
                if (config.ShouldDeleteIfMigrationNeeded)
                {
                    DeleteRealm(config);
                }
                else
                {
                    throw; // rethrow te exception
                    //TODO when have Migration but also consider programmer control over auto migration
                    //MigrateRealm(configuration);
                }
                // create after deleting old reopen after migrating
                srPtr = NativeSharedRealm.open(schemaHandle,
                                               databasePath, (IntPtr)databasePath.Length,
                                               readOnly, durability,
                                               config.EncryptionKey,
                                               config.SchemaVersion);
            }

            RuntimeHelpers.PrepareConstrainedRegions();
            try { /* Retain handle in a constrained execution region */ }
            finally
            {
                srHandle.SetHandle(srPtr);
            }

            return(new Realm(srHandle, config));
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Determines whether the specified RealmConfiguration is equal to the current RealmConfiguration.
 /// </summary>
 /// <param name="rhs">The <see cref="System.Object"/> to compare with the current RealmConfiguration.</param>
 /// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
 /// <see cref="Realms.RealmConfiguration"/>; otherwise, <c>false</c>.</returns>
 public bool Equals(RealmConfiguration rhs)
 {
     RealmPCLHelpers.ThrowProxyShouldNeverBeUsed();
     return(false);
 }
Ejemplo n.º 15
0
        public void ReadOnlyFilesMustExist()
        {
            // Arrange
            var config = new RealmConfiguration("FileNotThere.realm");
            config.IsReadOnly = true;

            // Assert
            Assert.Throws<RealmFileNotFoundException>(() =>
            {
                Realm.GetInstance(config);
            });
        }
Ejemplo n.º 16
0
 /// <summary>
 ///  Deletes all the files associated with a realm. Hides knowledge of the auxiliary filenames from the programmer.
 /// </summary>
 /// <param name="configuration">A configuration which supplies the realm path.</param>
 public static void DeleteRealm(RealmConfiguration configuration)
 {
     RealmPCLHelpers.ThrowProxyShouldNeverBeUsed();
 }
Ejemplo n.º 17
0
        public void MigrationTriggersDelete()
        {
            // Arrange
            var config = new RealmConfiguration("MigrateWWillRecreate.realm")
            {
                ShouldDeleteIfMigrationNeeded = true
            };
            Realm.DeleteRealm(config);
            Assert.False(File.Exists(config.DatabasePath));

            TestHelpers.CopyBundledDatabaseToDocuments(
                "ForMigrationsToCopyAndMigrate.realm", "MigrateWWillRecreate.realm");

            // Act - should cope by deleting and silently recreating
            var realm = Realm.GetInstance(config);

            // Assert
            Assert.That(File.Exists(config.DatabasePath));
        }
Ejemplo n.º 18
0
        public void EncryptionKeyMustBe64Bytes()
        {
            ReliesOnEncryption();

            // Arrange
            var config = new RealmConfiguration("EncryptionKeyMustBe64Bytes.realm");
            var smallKey = new byte[] { 1, 2, 3 };
            var bigKey = new byte[656];

            // Assert
            Assert.Throws<FormatException>(() => config.EncryptionKey = smallKey);
            Assert.Throws<FormatException>(() => config.EncryptionKey = bigKey);
        }
Ejemplo n.º 19
0
        public void CanSetDefaultConfiguration()
        {
            // Arrange
            var config = new RealmConfiguration();
            RealmConfiguration.DefaultConfiguration = config.ConfigWithPath("fred.realm");

            // Assert
            Assert.That(RealmConfiguration.DefaultConfiguration.DatabasePath, Is.StringEnding("fred.realm"));
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Factory for a Realm instance for this thread.
 /// </summary>
 /// <param name="config">Optional configuration.</param>
 /// <returns>A realm instance.</returns>
 /// <exception cref="RealmFileAccessErrorException">Throws error if the file system returns an error, preventing file creation.</exception>
 public static Realm GetInstance(RealmConfiguration config = null)
 {
     return(GetInstance(config ?? RealmConfiguration.DefaultConfiguration, null));
 }
Ejemplo n.º 21
0
        public void RealmWithOneClassWritesDesiredClass()
        {
            // Arrange
            var config = new RealmConfiguration("RealmWithOneClass.realm");
            Realm.DeleteRealm(config);
            config.ObjectClasses = new Type[] { typeof(LoneClass) };

            // Act
            using (var lonelyRealm = Realm.GetInstance(config))
            {
                lonelyRealm.Write(() =>
                {
                    lonelyRealm.Add(new LoneClass
                    {
                        Name = "The Singular"
                    });
                });

                // Assert
                Assert.That(lonelyRealm.All<LoneClass>().Count(), Is.EqualTo(1));
            }
        }
Ejemplo n.º 22
0
        public void UnableToOpenWithDifferentKey()
        {
            ReliesOnEncryption();

            // Arrange
            var config = new RealmConfiguration("UnableToOpenWithDifferentKey.realm");
            Realm.DeleteRealm(config);  // ensure guarded from prev tests
            var emptyKey = new byte[64];
            config.EncryptionKey = emptyKey;
            var openedWithKey = Realm.GetInstance(config);
            openedWithKey.Dispose();
            config.EncryptionKey[0] = 42;

            // Assert
            Assert.Throws<RealmFileAccessErrorException>(() =>
            {
                using (Realm.GetInstance(config))
                {
                }
            });
        }
Ejemplo n.º 23
0
        public void RealmObjectClassesOnlyAllowRealmObjects()
        {
            // Arrange
            var config = new RealmConfiguration("RealmWithOneClass.realm");
            Realm.DeleteRealm(config);
            config.ObjectClasses = new Type[] { typeof(LoneClass), typeof(object) };

            // Act and assert
            // Can't have classes in the list which are not RealmObjects
            Assert.That(() => Realm.GetInstance(config), Throws.TypeOf<ArgumentException>());
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Factory for a Realm instance for this thread.
 /// </summary>
 /// <param name="config">Optional configuration.</param>
 /// <returns>A realm instance.</returns>
 /// <exception cref="RealmFileAccessErrorException">Throws error if the filesystem has an error preventing file creation.</exception>
 public static Realm GetInstance(RealmConfiguration config = null)
 {
     return(GetInstance(config, null));
 }
Ejemplo n.º 25
0
        public void ReadOnlyRealmsArentWritable()
        {
            // Arrange
            var config = new RealmConfiguration("WillBeReadonly.realm");
            Realm.DeleteRealm(config);  // ensure start clean
            config.SchemaVersion = 0;  // must set version before file can be opened readOnly
            using (var openToCreate = Realm.GetInstance(config))
            {
                openToCreate.Write(() =>
                {
                    openToCreate.Add(new Person());
                });
            }

            config.IsReadOnly = true;

            using (var openedReadonly = Realm.GetInstance(config))
            {
                // Assert
                Assert.Throws<RealmInvalidTransactionException>(() =>
                {
                    openedReadonly.Write(() =>
                    {
                        openedReadonly.Add(new Person());
                    });
                });
            }
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Factory for a Realm instance for this thread.
 /// </summary>
 /// <param name="config">Optional configuration.</param>
 /// <returns>A realm instance.</returns>
 /// <exception cref="RealmFileAccessErrorException">Throws error if the file system returns an error, preventing file creation.</exception>
 //// [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
 public static Realm GetInstance(RealmConfiguration config = null)
 {
     RealmPCLHelpers.ThrowProxyShouldNeverBeUsed();
     return(null);
 }  // GetInstance
Ejemplo n.º 27
0
        public void ExceptionInMigrationCallback()
        {
            TestHelpers.CopyBundledDatabaseToDocuments(
                "ForMigrationsToCopyAndMigrate.realm", "NeedsMigrating.realm");

            var dummyException = new Exception();

            var configuration = new RealmConfiguration("NeedsMigrating.realm") { SchemaVersion = 100 };
            configuration.MigrationCallback = (migration, oldSchemaVersion) =>
            {
                throw dummyException;
            };

            var ex = Assert.Throws<AggregateException>(() => Realm.GetInstance(configuration).Dispose());
            Assert.That(ex.Flatten().InnerException, Is.SameAs(dummyException));
        }
Ejemplo n.º 28
0
        public void DeleteRealmFailsIfOpenSameThread()
        {
            // Arrange
            var config = new RealmConfiguration();
            var openRealm = Realm.GetInstance(config);

            // Assert
            Assert.Throws<RealmPermissionDeniedException>(() => Realm.DeleteRealm(config));
        }
Ejemplo n.º 29
0
        public void AddAnObjectFromAnotherRealmShouldFail()
        {
            Person p = null;
            _realm.Write(() => p = _realm.Add(new Person()));

            var secondaryConfig = new RealmConfiguration("AddAnObjectFromAnotherRealmShouldFail");
            Realm.DeleteRealm(secondaryConfig);
            using (var otherRealm = Realm.GetInstance(secondaryConfig))
            {
                Assert.That(() => otherRealm.Add(p), Throws.TypeOf<RealmObjectManagedByAnotherRealmException>());
            }
        }
Ejemplo n.º 30
0
        public void RealmWithOneClassThrowsIfUseOther()
        {
            // Arrange
            var config = new RealmConfiguration("RealmWithOneClass.realm");
            Realm.DeleteRealm(config);
            config.ObjectClasses = new Type[] { typeof(LoneClass) };

            // Act and assert
            using (var lonelyRealm = Realm.GetInstance(config))
            {
                // Can't create an object with a class not included in this Realm
                lonelyRealm.Write(() =>
                {
                    Assert.That(() => lonelyRealm.Add(new Person()), Throws.TypeOf<ArgumentException>());
                });
            }
        }
Ejemplo n.º 31
0
        public void IndexedDateTimeOffsetTest()
        {
            // Arrange
            var config = new RealmConfiguration
            {
                ObjectClasses = new[] { typeof(IndexedDateTimeOffsetObject) }
            };

            // Act and "assert" that no exception is thrown here
            using (Realm.GetInstance(config))
            {
            }
        }
Ejemplo n.º 32
0
        public void Compact_ShouldReduceSize(bool encrypt, bool populate)
        {
            var config = new RealmConfiguration($"compactrealm_{encrypt}_{populate}.realm");
            if (encrypt)
            {
                config.EncryptionKey = new byte[64];
                config.EncryptionKey[0] = 5;
            }

            Realm.DeleteRealm(config);

            using (var realm = Realm.GetInstance(config))
            {
                if (populate)
                {
                    AddDummyData(realm);
                }
            }

            var initialSize = new FileInfo(config.DatabasePath).Length;

            Assert.That(Realm.Compact(config));

            var finalSize = new FileInfo(config.DatabasePath).Length;
            Assert.That(initialSize >= finalSize);

            using (var realm = Realm.GetInstance(config))
            {
                Assert.That(realm.All<IntPrimaryKeyWithValueObject>().Count(), Is.EqualTo(populate ? 500 : 0));
            }
        }
Ejemplo n.º 33
0
 internal Migration(RealmConfiguration configuration, RealmSchema schema)
 {
     Configuration = configuration;
     Schema        = schema;
     _handle       = GCHandle.Alloc(this);
 }
Ejemplo n.º 34
0
 internal Migration(RealmConfiguration configuration, RealmSchema schema)
 {
     Configuration = configuration;
     Schema        = schema;
 }
Ejemplo n.º 35
0
 internal Migration(RealmConfiguration configuration, RealmSchema schema)
 {
     _configuration = configuration;
     _schema = schema;
 }