Beispiel #1
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, ReadOnly = 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);
        }
Beispiel #2
0
        internal Realm(SharedRealmHandle sharedRealmHandle, RealmConfigurationBase config, RealmSchema schema)
        {
            Config = config;

            State state = null;

            if (config.EnableCache)
            {
                var statePtr = sharedRealmHandle.GetManagedStateHandle();
                if (statePtr != IntPtr.Zero)
                {
                    state = GCHandle.FromIntPtr(statePtr).Target as State;
                }
            }

            if (state == null)
            {
                state = new State();
                sharedRealmHandle.SetManagedStateHandle(GCHandle.ToIntPtr(state.GCHandle));

                if (config.EnableCache)
                {
                    _states.Value[config.DatabasePath] = new WeakReference <State>(state);
                }
            }

            state.AddRealm(this);

            _state = state;

            SharedRealmHandle = sharedRealmHandle;
            Metadata          = schema.ToDictionary(t => t.Name, CreateRealmObjectMetadata);
            Schema            = schema;
        }
Beispiel #3
0
        internal Realm(SharedRealmHandle sharedRealmHandle, RealmConfiguration config, RealmSchema schema)
        {
            SharedRealmHandle = sharedRealmHandle;
            Config            = config;

            Metadata = schema.ToDictionary(t => t.Name, CreateRealmObjectMetadata);
            Schema   = schema;
        }
        public static IntPtr Open(Native.Configuration configuration, RealmSchema schema, byte[] encryptionKey)
        {
            var marshaledSchema = new SchemaMarshaler(schema);

            var result = NativeMethods.open(configuration, marshaledSchema.Objects, marshaledSchema.Objects.Length, marshaledSchema.Properties, encryptionKey, out NativeException nativeException);

            nativeException.ThrowIfNecessary();
            return(result);
        }
        internal override Realm CreateRealm(RealmSchema schema)
        {
            var configuration = CreateNativeConfiguration();

            configuration.in_memory = true;

            var srPtr = SharedRealmHandle.Open(configuration, schema, EncryptionKey);

            return(new Realm(new SharedRealmHandle(srPtr), this, schema));
        }
Beispiel #6
0
        /// <summary>
        /// Factory for asynchronously obtaining a <see cref="Realm"/> instance.
        /// </summary>
        /// <remarks>
        /// If the configuration points to a remote realm belonging to a Realm Object Server
        /// the realm will be downloaded and fully synchronized with the server prior to the completion
        /// of the returned Task object.
        /// Otherwise this method behaves identically to <see cref="GetInstance(RealmConfigurationBase)"/>
        /// and immediately returns a completed Task.
        /// </remarks>
        /// <returns>A <see cref="Task{Realm}"/> that is completed once the remote realm is fully synchronized or immediately if it's a local realm.</returns>
        /// <param name="config">A configuration object that describes the realm.</param>
        public static Task<Realm> GetInstanceAsync(RealmConfigurationBase config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            var schema = config.ObjectClasses != null ? RealmSchema.CreateSchemaForClasses(config.ObjectClasses) : RealmSchema.Default;
            return config.CreateRealmAsync(schema);
        }
Beispiel #7
0
        internal static Realm GetInstance(RealmConfiguration config, RealmSchema schema)
        {
            config = config ?? RealmConfiguration.DefaultConfiguration;

            var srHandle = new SharedRealmHandle();

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

            var configuration = new Native.Configuration
            {
                Path      = config.DatabasePath,
                read_only = config.ReadOnly,
                delete_if_migration_needed = config.ShouldDeleteIfMigrationNeeded,
                schema_version             = config.SchemaVersion
            };

            Migration migration = null;

            if (config.MigrationCallback != null)
            {
                migration = new Migration(config, schema);
                migration.PopulateConfiguration(ref configuration);
            }

            var srPtr = IntPtr.Zero;

            try
            {
                srPtr = srHandle.Open(configuration, schema, config.EncryptionKey);
            }
            catch (ManagedExceptionDuringMigrationException)
            {
                throw new AggregateException("Exception occurred in a Realm migration callback. See inner exception for more details.", migration?.MigrationException);
            }

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

            return(new Realm(srHandle, config, schema));
        }
        public RealmSchema GetSchema()
        {
            RealmSchema            result   = null;
            Action <Native.Schema> callback = (nativeSmallSchema) => result = RealmSchema.CreateFromObjectStoreSchema(nativeSmallSchema);

            // The callbackHandle will get freed in SharedRealmHandle.GetNativeSchema.
            var callbackHandle = GCHandle.Alloc(callback);

            NativeMethods.get_schema(this, GCHandle.ToIntPtr(callbackHandle), out var nativeException);
            nativeException.ThrowIfNecessary();

            return(result);
        }
        internal override Realm CreateRealm(RealmSchema schema)
        {
            var configuration = new Configuration
            {
                Path           = DatabasePath,
                schema_version = SchemaVersion,
                enable_cache   = EnableCache,
                in_memory      = true
            };

            var srPtr = IntPtr.Zero;

            srPtr = SharedRealmHandle.Open(configuration, schema, EncryptionKey);
            return(new Realm(new SharedRealmHandle(srPtr), this, schema));
        }
Beispiel #10
0
        internal override async Task <Realm> CreateRealmAsync(RealmSchema schema)
        {
            // If we are on UI thread will be set but often also set on long-lived workers to use Post back to UI thread.
            if (System.Threading.SynchronizationContext.Current != null)
            {
                await Task.Run(() =>
                {
                    using (CreateRealm(schema))
                    {
                    }
                });
            }

            return(CreateRealm(schema));
        }
Beispiel #11
0
        internal override Task <Realm> CreateRealmAsync(RealmSchema schema)
        {
            // Can't use async/await due to mono inliner bugs
            // If we are on UI thread will be set but often also set on long-lived workers to use Post back to UI thread.
            if (AsyncHelper.TryGetScheduler(out var scheduler))
            {
                return(Task.Run(() =>
                {
                    using (CreateRealm(schema))
                    {
                    }
                }).ContinueWith(_ => CreateRealm(schema), scheduler));
            }

            return(Task.FromResult(CreateRealm(schema)));
        }
        internal override Realm CreateRealm(RealmSchema schema)
        {
            var configuration = new Configuration
            {
                Path      = DatabasePath,
                read_only = IsReadOnly,
                delete_if_migration_needed = ShouldDeleteIfMigrationNeeded,
                schema_version             = SchemaVersion
            };

            Migration migration = null;

            if (MigrationCallback != null)
            {
                migration = new Migration(this, schema);
                migration.PopulateConfiguration(ref configuration);
            }

            if (ShouldCompactOnLaunch != null)
            {
                var handle = GCHandle.Alloc(ShouldCompactOnLaunch);
                configuration.should_compact_callback         = ShouldCompactOnLaunchCallback;
                configuration.managed_should_compact_delegate = GCHandle.ToIntPtr(handle);
            }

            var srPtr = IntPtr.Zero;

            try
            {
                srPtr = SharedRealmHandle.Open(configuration, schema, EncryptionKey);
            }
            catch (ManagedExceptionDuringMigrationException)
            {
                throw new AggregateException("Exception occurred in a Realm migration callback. See inner exception for more details.", migration?.MigrationException);
            }

            var srHandle = new SharedRealmHandle();

            srHandle.SetHandle(srPtr);
            if (Dynamic && !schema.Any())
            {
                srHandle.GetSchema(nativeSchema => schema = RealmSchema.CreateFromObjectStoreSchema(nativeSchema));
            }

            return(new Realm(srHandle, this, schema));
        }
Beispiel #13
0
        internal static Realm GetInstance(RealmConfigurationBase config, RealmSchema schema)
        {
            Argument.NotNull(config, nameof(config));

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

            return(config.CreateRealm(schema));
        }
        internal override Task <Realm> CreateRealmAsync(RealmSchema schema)
        {
            // Can't use async/await due to mono inliner bugs
            // If we are on UI thread will be set but often also set on long-lived workers to use Post back to UI thread.
            var scheduler = SynchronizationContext.Current != null?TaskScheduler.FromCurrentSynchronizationContext() : null;

            if (scheduler != null)
            {
                return(Task.Run(() =>
                {
                    using (CreateRealm(schema))
                    {
                    }
                }).ContinueWith(_ => CreateRealm(schema), scheduler));
            }

            return(Task.FromResult(CreateRealm(schema)));
        }
Beispiel #15
0
        public RealmSchema GetSchema()
        {
            RealmSchema            result   = null;
            Action <Native.Schema> callback = schema => result = RealmSchema.CreateFromObjectStoreSchema(schema);
            var handle = GCHandle.Alloc(callback);

            try
            {
                NativeMethods.get_schema(this, GCHandle.ToIntPtr(handle), out var nativeException);
                nativeException.ThrowIfNecessary();
            }
            finally
            {
                handle.Free();
            }

            return(result);
        }
Beispiel #16
0
        internal override Realm CreateRealm(RealmSchema schema)
        {
            var configuration = CreateNativeConfiguration();
            configuration.delete_if_migration_needed = ShouldDeleteIfMigrationNeeded;
            configuration.read_only = IsReadOnly;

            Migration migration = null;
            if (MigrationCallback != null)
            {
                migration = new Migration(this, schema);
                configuration.managed_migration_handle = GCHandle.ToIntPtr(migration.MigrationHandle);
            }

            GCHandle? shouldCompactHandle = null;
            if (ShouldCompactOnLaunch != null)
            {
                shouldCompactHandle = GCHandle.Alloc(ShouldCompactOnLaunch);
                configuration.managed_should_compact_delegate = GCHandle.ToIntPtr(shouldCompactHandle.Value);
            }

            var srPtr = IntPtr.Zero;
            try
            {
                srPtr = SharedRealmHandle.Open(configuration, schema, EncryptionKey);
            }
            catch (ManagedExceptionDuringMigrationException)
            {
                throw new AggregateException("Exception occurred in a Realm migration callback. See inner exception for more details.", migration?.MigrationException);
            }
            finally
            {
                migration?.ReleaseHandle();
                shouldCompactHandle?.Free();
            }

            var srHandle = new SharedRealmHandle(srPtr);
            if (IsDynamic && !schema.Any())
            {
                schema = srHandle.GetSchema();
            }

            return new Realm(srHandle, this, schema);
        }
            internal SchemaMarshaler(RealmSchema schema)
            {
                var properties = new List <Native.SchemaProperty>();

                Objects = schema.Select(@object =>
                {
                    var start = properties.Count;

                    properties.AddRange(@object.Select(ForMarshalling));

                    return(new Native.SchemaObject
                    {
                        name = @object.Name,
                        properties_start = start,
                        properties_end = properties.Count
                    });
                }).ToArray();
                Properties = properties.ToArray();
            }
            public SchemaMarshaler(RealmSchema schema)
            {
                var properties = new List <SchemaProperty>();

                Objects = schema.Select(@object =>
                {
                    var start = properties.Count;

                    properties.AddRange(@object.Select(ForMarshalling));

                    return(new SchemaObject
                    {
                        name = @object.Name,
                        properties_start = start,
                        properties_end = properties.Count,
                        is_embedded = @object.IsEmbedded,
                    });
                }).ToArray();
                Properties = properties.ToArray();
            }
Beispiel #19
0
        internal static Realm GetInstance(RealmConfigurationBase 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));
        }
Beispiel #20
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);
        }
Beispiel #21
0
        /// <summary>
        /// Factory for asynchronously obtaining a <see cref="Realm"/> instance.
        /// </summary>
        /// <remarks>
        /// If the configuration points to a remote realm belonging to a Realm Object Server
        /// the realm will be downloaded and fully synchronized with the server prior to the completion
        /// of the returned Task object.
        /// Otherwise this method behaves identically to <see cref="GetInstance(RealmConfigurationBase)"/>
        /// and immediately returns a completed Task.
        /// </remarks>
        /// <returns>A <see cref="Task{Realm}"/> that is completed once the remote realm is fully synchronized or immediately if it's a local realm.</returns>
        /// <param name="config">A configuration object that describes the realm.</param>
        public static Task <Realm> GetInstanceAsync(RealmConfigurationBase config = null)
        {
            if (config == null)
            {
                config = RealmConfiguration.DefaultConfiguration;
            }

            RealmSchema schema;

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

            return(config.CreateRealmAsync(schema));
        }
Beispiel #22
0
        /// <summary>
        /// Factory for asynchronously obtaining a <see cref="Realm"/> instance.
        /// </summary>
        /// <remarks>
        /// If the configuration points to a remote realm belonging to a Realm Object Server
        /// the realm will be downloaded and fully synchronized with the server prior to the completion
        /// of the returned Task object.
        /// Otherwise this method behaves identically to <see cref="GetInstance(RealmConfigurationBase)"/>
        /// and immediately returns a completed Task.
        /// </remarks>
        /// <returns>A <see cref="Task{Realm}"/> that is completed once the remote realm is fully synchronized or immediately if it's a local realm.</returns>
        /// <param name="config">A configuration object that describes the realm.</param>
        public static Task <Realm> GetInstanceAsync(RealmConfigurationBase config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            RealmSchema schema;

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

            return(config.CreateRealmAsync(schema));
        }
 internal override Task <Realm> CreateRealmAsync(RealmSchema schema, CancellationToken cancellationToken)
 {
     return(Task.FromResult(CreateRealm(schema)));
 }
 internal abstract Task <Realm> CreateRealmAsync(RealmSchema schema);
Beispiel #25
0
 // Due to a Xamarin bug (https://bugzilla.xamarin.com/show_bug.cgi?id=54617), we can't
 // provide a proper implementation in Debug.
 internal override Task <Realm> CreateRealmAsync(RealmSchema schema)
 {
     return(Task.FromResult(CreateRealm(schema)));
 }
 internal abstract Realm CreateRealm(RealmSchema schema);
Beispiel #27
0
 internal Migration(RealmConfiguration configuration, RealmSchema schema)
 {
     Configuration = configuration;
     Schema        = schema;
 }
Beispiel #28
0
        internal Realm(SharedRealmHandle sharedRealmHandle, RealmConfigurationBase config, RealmSchema schema)
        {
            RealmState state = null;

            var statePtr = sharedRealmHandle.GetManagedStateHandle();

            if (statePtr != IntPtr.Zero)
            {
                state = GCHandle.FromIntPtr(statePtr).Target as RealmState;
            }

            if (state == null)
            {
                state = new RealmState();
                sharedRealmHandle.SetManagedStateHandle(GCHandle.ToIntPtr(state.GCHandle));
            }

            state.AddRealm(this);
            _state = state;

            SharedRealmHandle = sharedRealmHandle;
            Config            = config;

            Metadata = schema.ToDictionary(t => t.Name, CreateRealmObjectMetadata);
            Schema   = schema;
        }
        public static SharedRealmHandle OpenWithSync(Configuration configuration, Sync.Native.SyncConfiguration syncConfiguration, RealmSchema schema, byte[] encryptionKey)
        {
            var marshaledSchema = new SchemaMarshaler(schema);

            var result = NativeMethods.open_with_sync(configuration, syncConfiguration, marshaledSchema.Objects, marshaledSchema.Objects.Length, marshaledSchema.Properties, encryptionKey, out var nativeException);

            nativeException.ThrowIfNecessary();

            return(new SharedRealmHandle(result));
        }
        public static AsyncOpenTaskHandle OpenWithSyncAsync(Configuration configuration, Sync.Native.SyncConfiguration syncConfiguration, RealmSchema schema, byte[] encryptionKey, GCHandle tcsHandle)
        {
            var marshaledSchema = new SchemaMarshaler(schema);

            var asyncTaskPtr = NativeMethods.open_with_sync_async(configuration, syncConfiguration, marshaledSchema.Objects, marshaledSchema.Objects.Length, marshaledSchema.Properties, encryptionKey, GCHandle.ToIntPtr(tcsHandle), out var nativeException);

            nativeException.ThrowIfNecessary();
            var asyncTaskHandle = new AsyncOpenTaskHandle(asyncTaskPtr);

            return(asyncTaskHandle);
        }