private void AddInternal(RealmObject obj, Type objectType, bool update) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (objectType == null) { throw new ArgumentNullException(nameof(objectType)); } if (obj.IsManaged) { if (obj.Realm.SharedRealmHandle == this.SharedRealmHandle) { // Already managed by this realm, so nothing to do. return; } throw new RealmObjectManagedByAnotherRealmException("Cannot start to manage an object with a realm when it's already managed by another realm"); } if (!Metadata.TryGetValue(objectType.Name, out var metadata)) { throw new ArgumentException($"The class {objectType.Name} is not in the limited set of classes for this realm"); } var objectPtr = IntPtr.Zero; if (update && metadata.Helper.TryGetPrimaryKeyValue(obj, out var pkValue)) { switch (pkValue) { case string stringValue: objectPtr = metadata.Table.Find(SharedRealmHandle, stringValue); break; case null: objectPtr = metadata.Table.Find(SharedRealmHandle, (long?)null); break; default: // We know it must be convertible to long, so optimistically do it. objectPtr = metadata.Table.Find(SharedRealmHandle, Convert.ToInt64(pkValue)); break; } } var setPrimaryKey = false; if (objectPtr == IntPtr.Zero) { objectPtr = metadata.Table.AddEmptyObject(SharedRealmHandle); setPrimaryKey = true; } var objectHandle = CreateObjectHandle(objectPtr, SharedRealmHandle); obj._SetOwner(this, objectHandle, metadata); metadata.Helper.CopyToRealm(obj, update, setPrimaryKey); obj.OnManaged(); }
private void AddInternal(RealmObject obj, Type objectType, bool update) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (objectType == null) { throw new ArgumentNullException(nameof(objectType)); } if (obj.IsManaged) { if (obj.Realm.SharedRealmHandle == this.SharedRealmHandle) { // Already managed by this realm, so nothing to do. return; } throw new RealmObjectManagedByAnotherRealmException("Cannot start to manage an object with a realm when it's already managed by another realm"); } var objectName = objectType.GetTypeInfo().GetMappedOrOriginalName(); if (!Metadata.TryGetValue(objectName, out var metadata)) { throw new ArgumentException($"The class {objectType.Name} is not in the limited set of classes for this realm"); } ObjectHandle objectHandle; bool isNew; if (metadata.Helper.TryGetPrimaryKeyValue(obj, out var primaryKey)) { var pkProperty = metadata.Schema.PrimaryKeyProperty.Value; objectHandle = SharedRealmHandle.CreateObjectWithPrimaryKey(pkProperty, primaryKey, metadata.Table, objectName, update, out isNew); } else { isNew = true; // Objects without PK are always new objectHandle = SharedRealmHandle.CreateObject(metadata.Table); } obj._SetOwner(this, objectHandle, metadata); // If an object is newly created, we don't need to invoke setters of properties with default values. metadata.Helper.CopyToRealm(obj, update, isNew); obj.OnManaged(); }