All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.permazen.core.ReferenceField Maven / Gradle / Ivy


/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.core;

import com.google.common.base.Preconditions;

import io.permazen.core.type.ReferenceFieldType;
import io.permazen.core.util.ObjIdMap;
import io.permazen.util.ByteReader;

import java.util.Set;
import java.util.SortedSet;

/**
 * A field that references another {@link Database} object.
 *
 * 

* Null values sort last. * *

* Reference fields are always indexed. */ public class ReferenceField extends SimpleField { final DeleteAction onDelete; final boolean cascadeDelete; final boolean allowDeleted; final boolean allowDeletedSnapshot; /** * Constructor. * * @param name the name of the field * @param storageId field storage ID * @param schema schema version * @param onDelete deletion behavior * @param cascadeDelete whether to cascade deletes * @param allowDeleted whether to allow assignment to deleted obects in normal transactions * @param allowDeletedSnapshot whether to allow assignment to deleted obects in snapshot transactions * @param objectTypes allowed object type storage IDs, or null for no restriction * @throws IllegalArgumentException if any parameter is null * @throws IllegalArgumentException if {@code name} is invalid * @throws IllegalArgumentException if {@code storageId} is invalid */ ReferenceField(String name, int storageId, Schema schema, DeleteAction onDelete, boolean cascadeDelete, boolean allowDeleted, boolean allowDeletedSnapshot, Set objectTypes) { super(name, storageId, schema, new ReferenceFieldType(objectTypes), true); Preconditions.checkArgument(onDelete != null, "null onDelete"); this.onDelete = onDelete; this.cascadeDelete = cascadeDelete; this.allowDeleted = allowDeleted; this.allowDeletedSnapshot = allowDeletedSnapshot; } // Public methods /** * Get the desired behavior when an object referred to by this field is deleted. * * @return desired behavior when a referenced object is deleted */ public DeleteAction getOnDelete() { return this.onDelete; } /** * Determine whether the referred-to object should be deleted when an object containing this field is deleted. * * @return whether deletion should cascade to the referred-to object */ public boolean isCascadeDelete() { return this.cascadeDelete; } /** * Determine whether this field accepts references to deleted objects in normal (non-snapshot) transactions. * * @return whether deleted objects are allowed in normal transactions */ public boolean isAllowDeleted() { return this.allowDeleted; } /** * Determine whether this field accepts references to deleted objects in snapshot transactions. * * @return whether deleted objects are allowed in snapshot transactions */ public boolean isAllowDeletedSnapshot() { return this.allowDeletedSnapshot; } /** * Get the object types this field is allowed to reference, if so restricted. * * @return storage IDs of allowed object types, or null if there is no restriction */ public SortedSet getObjectTypes() { return ((ReferenceFieldType)this.fieldType).getObjectTypes(); } @Override public R visit(FieldSwitch target) { return target.caseReferenceField(this); } @Override public String toString() { return "reference field `" + this.name + "'"; } // Non-public methods @Override protected boolean remapsObjectId() { return true; } @Override protected ObjId remapObjectId(ObjIdMap objectIdMap, ObjId srcId) { if (srcId == null || objectIdMap == null || !objectIdMap.containsKey(srcId)) return srcId; final ObjId dstId = objectIdMap.get(srcId); Preconditions.checkArgument(dstId != null, "can't copy " + srcId + " because " + srcId + " is remapped to null"); return dstId; } /** * Find any object referenced by this field in the source transaction that don't exist in the destination transaction. * This should work for both normal fields and sub-fields of complex fields. * * @param srcTx source transaction * @param dstTx destination transaction * @param id object containing the reference field * @see Transaction#checkDeletedAssignment */ void findAnyDeletedAssignments(Transaction srcTx, Transaction dstTx, ObjId id) { // Handle complex sub-field case if (this.parent != null) { for (ObjId targetId : this.parent.iterateSubField(srcTx, id, this)) dstTx.checkDeletedAssignment(id, this, targetId); return; } // Handle simple field case final byte[] value = srcTx.kvt.get(this.buildKey(id)); if (value == null) return; dstTx.checkDeletedAssignment(id, this, this.fieldType.read(new ByteReader(value))); } @Override boolean isUpgradeCompatible(Field field) { if (field.getClass() != this.getClass()) return false; return true; // we allow object type restrictions to differ } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy