//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private org.neo4j.internal.kernel.api.IndexReference getOrCreateUniquenessConstraintIndex(org.neo4j.internal.kernel.api.SchemaRead schemaRead, org.neo4j.internal.kernel.api.TokenRead tokenRead, org.neo4j.internal.kernel.api.schema.SchemaDescriptor schema, String provider) throws org.neo4j.internal.kernel.api.exceptions.schema.SchemaKernelException, org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException private IndexReference GetOrCreateUniquenessConstraintIndex(SchemaRead schemaRead, TokenRead tokenRead, SchemaDescriptor schema, string provider) { IndexReference descriptor = schemaRead.Index(schema); if (descriptor != IndexReference.NO_INDEX) { if (descriptor.Unique) { // OK so we found a matching constraint index. We check whether or not it has an owner // because this may have been a left-over constraint index from a previously failed // constraint creation, due to crash or similar, hence the missing owner. if (schemaRead.IndexGetOwningUniquenessConstraintId(descriptor) == null) { return(descriptor); } throw new AlreadyConstrainedException(ConstraintDescriptorFactory.uniqueForSchema(schema), SchemaKernelException.OperationContext.CONSTRAINT_CREATION, new SilentTokenNameLookup(tokenRead)); } // There's already an index for this schema descriptor, which isn't of the type we're after. throw new AlreadyIndexedException(schema, CONSTRAINT_CREATION); } IndexDescriptor indexDescriptor = CreateConstraintIndex(schema, provider); IndexProxy indexProxy = _indexingService.getIndexProxy(indexDescriptor.Schema()); return(indexProxy.Descriptor); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public void validate() throws org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException public override void Validate() { if (_failures.Count > 0) { SchemaDescriptor descriptor = Descriptor.schema(); throw new UniquePropertyValueValidationException(ConstraintDescriptorFactory.uniqueForSchema(descriptor), ConstraintValidationException.Phase.VERIFICATION, new HashSet <>(_failures) ); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldAbortConstraintCreationWhenDuplicatesExist() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldAbortConstraintCreationWhenDuplicatesExist() { // given Transaction transaction = newTransaction(AnonymousContext.writeToken()); // name is not unique for Foo in the existing data int foo = transaction.TokenWrite().labelGetOrCreateForName("Foo"); int name = transaction.TokenWrite().propertyKeyGetOrCreateForName("name"); long node1 = transaction.DataWrite().nodeCreate(); transaction.DataWrite().nodeAddLabel(node1, foo); transaction.DataWrite().nodeSetProperty(node1, name, Values.of("foo")); long node2 = transaction.DataWrite().nodeCreate(); transaction.DataWrite().nodeAddLabel(node2, foo); transaction.DataWrite().nodeSetProperty(node2, name, Values.of("foo")); commit(); // when LabelSchemaDescriptor descriptor = SchemaDescriptorFactory.forLabel(foo, name); try { SchemaWrite schemaWriteOperations = schemaWriteInNewTransaction(); schemaWriteOperations.UniquePropertyConstraintCreate(descriptor); fail("expected exception"); } // then catch (CreateConstraintFailureException ex) { assertEquals(ConstraintDescriptorFactory.uniqueForSchema(descriptor), ex.Constraint()); Exception cause = ex.InnerException; assertThat(cause, instanceOf(typeof(ConstraintValidationException))); string expectedMessage = string.Format("Both Node({0:D}) and Node({1:D}) have the label `Foo` and property `name` = 'foo'", node1, node2); string actualMessage = UserMessage(( ConstraintValidationException )cause); assertEquals(expectedMessage, actualMessage); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldNotDropUniquePropertyConstraintThatDoesNotExistWhenThereIsAPropertyExistenceConstraint() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldNotDropUniquePropertyConstraintThatDoesNotExistWhenThereIsAPropertyExistenceConstraint() { // given SchemaWrite schemaWriteOperations = schemaWriteInNewTransaction(); schemaWriteOperations.NodePropertyExistenceConstraintCreate(Descriptor); commit(); // when try { SchemaWrite statement = schemaWriteInNewTransaction(); statement.ConstraintDrop(ConstraintDescriptorFactory.uniqueForSchema(Descriptor)); fail("expected exception"); } // then catch (DropConstraintFailureException e) { assertThat(e.InnerException, instanceOf(typeof(NoSuchConstraintException))); } finally { rollback(); } { // then Transaction transaction = newTransaction(); IEnumerator <ConstraintDescriptor> constraints = transaction.SchemaRead().constraintsGetForSchema(Descriptor); assertEquals(ConstraintDescriptorFactory.existsForSchema(Descriptor), single(constraints)); commit(); } }
internal override UniquenessConstraintDescriptor NewConstraintObject(LabelSchemaDescriptor descriptor) { return(ConstraintDescriptorFactory.uniqueForSchema(descriptor)); }
/// <summary> /// You MUST hold a label write lock before you call this method. /// However the label write lock is temporarily released while populating the index backing the constraint. /// It goes a little like this: /// <ol> /// <li>Prerequisite: Getting here means that there's an open schema transaction which has acquired the /// LABEL WRITE lock.</li> /// <li>Index schema rule which is backing the constraint is created in a nested mini-transaction /// which doesn't acquire any locking, merely adds tx state and commits so that the index rule is applied /// to the store, which triggers the index population</li> /// <li>Release the LABEL WRITE lock</li> /// <li>Await index population to complete</li> /// <li>Acquire the LABEL WRITE lock (effectively blocking concurrent transactions changing /// data related to this constraint, and it so happens, most other transactions as well) and verify /// the uniqueness of the built index</li> /// <li>Leave this method, knowing that the uniqueness constraint rule will be added to tx state /// and this tx committed, which will create the uniqueness constraint</li> /// </ol> /// </summary> //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public long createUniquenessConstraintIndex(org.neo4j.kernel.impl.api.KernelTransactionImplementation transaction, org.neo4j.internal.kernel.api.schema.SchemaDescriptor descriptor, String provider) throws org.neo4j.internal.kernel.api.exceptions.TransactionFailureException, org.neo4j.internal.kernel.api.exceptions.schema.CreateConstraintFailureException, org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException, org.neo4j.kernel.api.exceptions.schema.AlreadyConstrainedException public virtual long CreateUniquenessConstraintIndex(KernelTransactionImplementation transaction, SchemaDescriptor descriptor, string provider) { UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForSchema(descriptor); _log.info("Starting constraint creation: %s.", constraint.OwnedIndexDescriptor()); IndexReference index; SchemaRead schemaRead = transaction.SchemaRead(); try { index = GetOrCreateUniquenessConstraintIndex(schemaRead, transaction.TokenRead(), descriptor, provider); } catch (AlreadyConstrainedException e) { throw e; } catch (Exception e) when(e is SchemaKernelException || e is IndexNotFoundKernelException) { throw new CreateConstraintFailureException(constraint, e); } bool success = false; bool reacquiredLabelLock = false; Locks_Client locks = transaction.StatementLocks().pessimistic(); try { long indexId = schemaRead.IndexGetCommittedId(index); IndexProxy proxy = _indexingService.getIndexProxy(indexId); // Release the LABEL WRITE lock during index population. // At this point the integrity of the constraint to be created was checked // while holding the lock and the index rule backing the soon-to-be-created constraint // has been created. Now it's just the population left, which can take a long time locks.ReleaseExclusive(descriptor.KeyType(), descriptor.KeyId()); AwaitConstraintIndexPopulation(constraint, proxy, transaction); _log.info("Constraint %s populated, starting verification.", constraint.OwnedIndexDescriptor()); // Index population was successful, but at this point we don't know if the uniqueness constraint holds. // Acquire LABEL WRITE lock and verify the constraints here in this user transaction // and if everything checks out then it will be held until after the constraint has been // created and activated. locks.AcquireExclusive(transaction.LockTracer(), descriptor.KeyType(), descriptor.KeyId()); reacquiredLabelLock = true; _indexingService.getIndexProxy(indexId).verifyDeferredConstraints(_nodePropertyAccessor); _log.info("Constraint %s verified.", constraint.OwnedIndexDescriptor()); success = true; return(indexId); } catch (SchemaKernelException e) { throw new System.InvalidOperationException(string.Format("Index ({0}) that we just created does not exist.", descriptor), e); } catch (IndexNotFoundKernelException e) { throw new TransactionFailureException(string.Format("Index ({0}) that we just created does not exist.", descriptor), e); } catch (IndexEntryConflictException e) { throw new UniquePropertyValueValidationException(constraint, VERIFICATION, e); } catch (Exception e) when(e is InterruptedException || e is IOException) { throw new CreateConstraintFailureException(constraint, e); } finally { if (!success) { if (!reacquiredLabelLock) { locks.AcquireExclusive(transaction.LockTracer(), descriptor.KeyType(), descriptor.KeyId()); } if (IndexStillExists(schemaRead, descriptor, index)) { DropUniquenessConstraintIndex(( IndexDescriptor )index); } } } }