示例#1
0
//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)
                                                                 );
            }
        }
示例#3
0
//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);
            }
        }
示例#4
0
//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();
            }
        }
示例#5
0
 internal override UniquenessConstraintDescriptor NewConstraintObject(LabelSchemaDescriptor descriptor)
 {
     return(ConstraintDescriptorFactory.uniqueForSchema(descriptor));
 }
示例#6
0
        /// <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);
                    }
                }
            }
        }