Пример #1
0
 public override void VisitUniqueConstraint(UniquenessConstraintDescriptor constraint, string userDescription)
 {
     if (!_uniquenessConstraints.Add(constraint))
     {
         throw new System.ArgumentException(format("Duplicated unique constraint %s for %s", constraint, userDescription));
     }
 }
        private void VisitAddedUniquenessConstraint(UniquenessConstraintDescriptor uniqueConstraint, long constraintId)
        {
            StoreIndexDescriptor indexRule = _schemaStorage.indexGetForSchema(uniqueConstraint.OwnedIndexDescriptor());

            _recordState.createSchemaRule(_constraintSemantics.createUniquenessConstraintRule(constraintId, uniqueConstraint, indexRule.Id));
            _recordState.setConstraintIndexOwner(indexRule, constraintId);
        }
Пример #3
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private void awaitConstraintIndexPopulation(org.neo4j.kernel.api.schema.constraints.UniquenessConstraintDescriptor constraint, org.neo4j.kernel.impl.api.index.IndexProxy proxy, org.neo4j.kernel.impl.api.KernelTransactionImplementation transaction) throws InterruptedException, org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException
        private void AwaitConstraintIndexPopulation(UniquenessConstraintDescriptor constraint, IndexProxy proxy, KernelTransactionImplementation transaction)
        {
            try
            {
                bool stillGoing;
                do
                {
                    stillGoing = proxy.AwaitStoreScanCompleted(1, TimeUnit.SECONDS);
                    if (transaction.Terminated)
                    {
                        throw new TransactionTerminatedException(transaction.ReasonIfTerminated.get());
                    }
                } while (stillGoing);
            }
            catch (IndexPopulationFailedKernelException e)
            {
                Exception cause = e.InnerException;
                if (cause is IndexEntryConflictException)
                {
                    throw new UniquePropertyValueValidationException(constraint, VERIFICATION, ( IndexEntryConflictException )cause);
                }
                else
                {
                    throw new UniquePropertyValueValidationException(constraint, VERIFICATION, e);
                }
            }
        }
Пример #4
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void constraintPropertyIdsNotUpdatedByConstraintEnforcer()
        public virtual void ConstraintPropertyIdsNotUpdatedByConstraintEnforcer()
        {
            UniquenessConstraintDescriptor   uniquenessConstraint = ConstraintDescriptorFactory.uniqueForLabel(1, 1, 70, 8);
            NodeKeyConstraintDescriptor      nodeKeyConstraint    = ConstraintDescriptorFactory.nodeKeyForLabel(2, 12, 7, 13);
            RelExistenceConstraintDescriptor relTypeConstraint    = ConstraintDescriptorFactory.existsForRelType(3, 5, 13, 8);
            IList <ConstraintDescriptor>     descriptors          = Arrays.asList(uniquenessConstraint, nodeKeyConstraint, relTypeConstraint);

            StorageReader storageReader = PrepareStorageReaderMock(descriptors);

            PropertyExistenceEnforcer.GetOrCreatePropertyExistenceEnforcerFrom(storageReader);

            assertArrayEquals("Property ids should remain untouched.", new int[] { 1, 70, 8 }, uniquenessConstraint.Schema().PropertyIds);
            assertArrayEquals("Property ids should remain untouched.", new int[] { 12, 7, 13 }, nodeKeyConstraint.Schema().PropertyIds);
            assertArrayEquals("Property ids should remain untouched.", new int[] { 5, 13, 8 }, relTypeConstraint.Schema().PropertyIds);
        }
Пример #5
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldValidateUniquenessIndexes() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
		 public virtual void ShouldValidateUniquenessIndexes()
		 {
			  // Given
			  NeoStores store = mock( typeof( NeoStores ) );
			  IndexingService indexes = mock( typeof( IndexingService ) );
			  IntegrityValidator validator = new IntegrityValidator( store, indexes );
			  UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForLabel( 1, 1 );

			  doThrow( new UniquePropertyValueValidationException( constraint, ConstraintValidationException.Phase.VERIFICATION, new Exception() ) ).when(indexes).validateIndex(2L);

			  ConstraintRule record = ConstraintRule.constraintRule( 1L, constraint, 2L );

			  // When
			  try
			  {
					validator.ValidateSchemaRule( record );
					fail( "Should have thrown integrity error." );
			  }
			  catch ( Exception )
			  {
					// good
			  }
		 }
Пример #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);
                    }
                }
            }
        }