• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-dotnet / 5716220196

31 Jul 2023 02:52PM UTC coverage: 82.478% (-0.3%) from 82.741%
5716220196

Pull #3261

github

aed2eb
fealebenpae
Merge remote-tracking branch 'origin/main' into yg/updated-marshaling

# Conflicts:
#	Realm/Realm/Handles/SharedRealmHandle.cs
Pull Request #3261: Use modern-er marshaling techniques

2029 of 2601 branches covered (78.01%)

Branch coverage included in aggregate %.

201 of 201 new or added lines in 21 files covered. (100.0%)

6246 of 7432 relevant lines covered (84.04%)

34048.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.68
/Realm/Realm/Configurations/RealmConfiguration.cs
1
////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2016 Realm Inc.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
////////////////////////////////////////////////////////////////////////////
18

19
using System.Runtime.InteropServices;
20
using System.Threading;
21
using System.Threading.Tasks;
22
using Realms.Helpers;
23
using Realms.Native;
24
using Realms.Schema;
25

26
namespace Realms
27
{
28
    /// <summary>
29
    /// Realm configuration specifying settings that affect the Realm's behavior.
30
    /// <br/>
31
    /// Its main role is generating a canonical path from whatever absolute, relative subdirectory, or just filename the user supplies.
32
    /// </summary>
33
    public class RealmConfiguration : RealmConfigurationBase
34
    {
35
        /// <summary>
36
        /// In order to handle manual migrations, you need to supply a migration callback to your
37
        /// <see cref="RealmConfiguration"/>. It will be called with a <see cref="Migration"/> instance containing
38
        /// the pre- and the post-migration <see cref="Realm"/>. You should make sure that the <see cref="Migration.NewRealm"/>
39
        /// property on it contains a database that is up to date when returning. The <c>oldSchemaVersion</c>
40
        /// parameter will tell you which <see cref="RealmConfigurationBase.SchemaVersion"/> the user is migrating
41
        /// <b>from</b>. They should always be migrating to the current <see cref="RealmConfigurationBase.SchemaVersion"/>.
42
        /// </summary>
43
        /// <param name="migration">
44
        /// The <see cref="Migration"/> instance, containing information about the old and the new <see cref="Realm"/>.
45
        /// </param>
46
        /// <param name="oldSchemaVersion">
47
        /// An unsigned long value indicating the <see cref="RealmConfigurationBase.SchemaVersion"/> of the old
48
        /// <see cref="Realm"/>.
49
        /// </param>
50
        public delegate void MigrationCallbackDelegate(Migration migration, ulong oldSchemaVersion);
51

52
        /// <summary>
53
        /// A callback, invoked when opening a Realm for the first time during the life
54
        /// of a process to determine if it should be compacted before being returned
55
        /// to the user.
56
        /// </summary>
57
        /// <param name="totalBytes">Total file size (data + free space).</param>
58
        /// <param name="bytesUsed">Total data size.</param>
59
        /// <returns><c>true</c> to indicate that an attempt to compact the file should be made.</returns>
60
        /// <remarks>The compaction will be skipped if another process is accessing it.</remarks>
61
        public delegate bool ShouldCompactDelegate(ulong totalBytes, ulong bytesUsed);
62

63
        /// <summary>
64
        /// Gets or sets a value indicating whether the database will be deleted if the <see cref="RealmSchema"/>
65
        /// mismatches the one in the code. Use this when debugging and developing your app but never release it with
66
        /// this flag set to <c>true</c>.
67
        /// </summary>
68
        /// <value><c>true</c> to delete the database on schema mismatch; <c>false</c> otherwise.</value>
69
        public bool ShouldDeleteIfMigrationNeeded { get; set; }
3,156✔
70

71
        /// <summary>
72
        /// Gets or sets a value indicating whether a <see cref="Realm"/> is opened as readonly. This allows opening it
73
        /// from locked locations such as resources, bundled with an application.
74
        /// </summary>
75
        /// <value><c>true</c> if the <see cref="Realm"/> will be opened as readonly; <c>false</c> otherwise.</value>
76
        public bool IsReadOnly { get; set; }
3,186✔
77

78
        /// <summary>
79
        /// Gets or sets the migration callback.
80
        /// </summary>
81
        /// <value>
82
        /// The <see cref="MigrationCallbackDelegate"/> that will be invoked if the <see cref="Realm"/> needs
83
        /// to be migrated.
84
        /// </value>
85
        public MigrationCallbackDelegate? MigrationCallback { get; set; }
3,193✔
86

87
        /// <summary>
88
        /// Gets or sets the compact on launch callback.
89
        /// </summary>
90
        /// <value>
91
        /// The <see cref="ShouldCompactDelegate"/> that will be invoked when opening a Realm for the first time
92
        /// to determine if it should be compacted before being returned to the user.
93
        /// </value>
94
        public ShouldCompactDelegate? ShouldCompactOnLaunch { get; set; }
3,159✔
95

96
        /// <summary>
97
        /// Gets or sets the key, used to encrypt the entire Realm. Once set, must be specified each time the file is used.
98
        /// </summary>
99
        /// <value>Full 64byte (512bit) key for AES-256 encryption.</value>
100
        public new byte[]? EncryptionKey
101
        {
102
            get => base.EncryptionKey;
3✔
103
            set => base.EncryptionKey = value;
20✔
104
        }
105

106
        private static RealmConfigurationBase? _defaultConfiguration;
107

108
        /// <summary>
109
        /// Gets or sets the <see cref="RealmConfigurationBase"/> that is used when creating a new <see cref="Realm"/> without specifying a configuration.
110
        /// </summary>
111
        /// <value>The default configuration.</value>
112
        public static RealmConfigurationBase DefaultConfiguration
113
        {
114
            get => _defaultConfiguration ??= new RealmConfiguration();
3,897!
115

116
            set
117
            {
118
                Argument.NotNull(value, nameof(value));
3,803✔
119
                _defaultConfiguration = value;
3,803✔
120
            }
3,803✔
121
        }
122

123
        /// <summary>
124
        /// Initializes a new instance of the <see cref="RealmConfiguration"/> class.
125
        /// </summary>
126
        /// <param name="optionalPath">Path to the realm, must be a valid full path for the current platform, relative subdirectory, or just filename.</param>
127
        public RealmConfiguration(string? optionalPath = null) : base(optionalPath)
7,531✔
128
        {
129
        }
7,531✔
130

131
        /// <summary>
132
        /// Clone method allowing you to override or customize the current path.
133
        /// </summary>
134
        /// <returns>An object with a fully-specified, canonical path.</returns>
135
        /// <param name="newConfigPath">Path to the realm, must be a valid full path for the current platform, relative subdirectory, or just filename.</param>
136
        public RealmConfiguration ConfigWithPath(string newConfigPath)
137
        {
138
            var ret = (RealmConfiguration)MemberwiseClone();
13✔
139
            ret.DatabasePath = GetPathToRealm(newConfigPath);
13✔
140
            return ret;
13✔
141
        }
142

143
        internal override SharedRealmHandle CreateHandle(in Configuration configuration)
144
            => SharedRealmHandle.Open(configuration);
3,148✔
145

146
        internal override Configuration CreateNativeConfiguration(Arena arena)
147
        {
148
            var result = base.CreateNativeConfiguration(arena);
3,155✔
149

150
            result.delete_if_migration_needed = ShouldDeleteIfMigrationNeeded;
3,155✔
151
            result.read_only = IsReadOnly;
3,155✔
152
            result.invoke_migration_callback = MigrationCallback != null;
3,155✔
153
            result.invoke_should_compact_callback = ShouldCompactOnLaunch != null;
3,155✔
154
            result.automatically_migrate_embedded = true;
3,155✔
155

156
            return result;
3,155✔
157
        }
158

159
        internal override Task<SharedRealmHandle> CreateHandleAsync(in Configuration configuration, CancellationToken cancellationToken)
160
        {
161
            // Can't use async/await due to mono inliner bugs
162
            // If we are on UI thread will be set but often also set on long-lived workers to use Post back to UI thread.
163
            if (AsyncHelper.TryGetScheduler(out var scheduler))
1!
164
            {
165
                // make a local copy because we can't capture in/ref/out parameters in lambdas
166
                var config = configuration;
1✔
167
                return Task.Run(() =>
1✔
168
                {
1✔
169
                    // make another copy so we can open a temporary realm on this worker thread
1✔
170
                    // to execute any migrations on the background
1✔
171
                    // without clobbering the original config's managed handle
1✔
172
                    var configCopy = config;
1✔
173
                    configCopy.managed_config = GCHandle.ToIntPtr(GCHandle.Alloc(this));
1✔
174
                    using (CreateHandle(configCopy))
1✔
175
                    {
1✔
176
                    }
1✔
177
                }, cancellationToken).ContinueWith(_ => CreateHandle(config), scheduler);
3✔
178
            }
179

180
            return Task.FromResult(CreateHandle(configuration));
×
181
        }
182
    }
183
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc