public List<DynamicRecord> allocateFrom( SchemaRule rule ) { List<DynamicRecord> records = new ArrayList<>(); DynamicRecord record = getRecord( rule.getId(), nextRecord(), CHECK ); DynamicRecordAllocator recordAllocator = new ReusableRecordsCompositeAllocator( singleton( record ), this ); allocateRecordsFromBytes( records, SchemaRuleSerialization.serialize( rule ), recordAllocator ); return records; }
@Test public void rulesCreatedWithoutNameMustRetainComputedNameAfterDeserialisation() throws Exception { assertThat( serialiseAndDeserialise( indexRegular ).getName(), is( "index_1" ) ); assertThat( serialiseAndDeserialise( indexUnique ).getName(), is( "index_2" ) ); assertThat( serialiseAndDeserialise( indexCompositeRegular ).getName(), is( "index_1" ) ); assertThat( serialiseAndDeserialise( indexCompositeUnique ).getName(), is( "index_2" ) ); assertThat( serialiseAndDeserialise( indexBigComposite ).getName(), is( "index_1" ) ); assertThat( serialiseAndDeserialise( constraintExistsLabel ).getName(), is( "constraint_1" ) ); assertThat( serialiseAndDeserialise( constraintUniqueLabel ).getName(), is( "constraint_2" ) ); assertThat( serialiseAndDeserialise( constraintNodeKeyLabel ).getName(), is( "constraint_2" ) ); assertThat( serialiseAndDeserialise( constraintExistsRelType ).getName(), is( "constraint_2" ) ); assertThat( serialiseAndDeserialise( constraintCompositeLabel ).getName(), is( "constraint_1" ) ); assertThat( serialiseAndDeserialise( constraintCompositeRelType ).getName(), is( "constraint_2" ) ); }
ConstraintRule( long id, ConstraintDescriptor descriptor, Long ownedIndex, String name ) { this.id = id; this.descriptor = descriptor; this.ownedIndex = ownedIndex; this.name = SchemaRule.nameOrDefault( name, "constraint_" + id ); }
private void checkSchema( SchemaRule rule, DynamicRecord record, RecordAccess records, CheckerEngine<DynamicRecord,ConsistencyReport.SchemaConsistencyReport> engine ) { rule.schema().processWith( new CheckSchema( engine, records ) ); checkForDuplicates( rule, record, engine ); }
private Collection<DynamicRecord> asRecords( SchemaRule rule, boolean inUse ) { // Only used to transfer List<DynamicRecord> records = new ArrayList<>(); DynamicRecord dynamicRecord = new DynamicRecord( rule.getId() ); dynamicRecord.setInUse( inUse ); records.add( dynamicRecord ); return records; }
void addSchemaRule( SchemaRule rule ) { if ( rule instanceof ConstraintRule ) { ConstraintRule constraintRule = (ConstraintRule) rule; constraintRuleById.put( constraintRule.getId(), constraintRule ); constraints.add( constraintSemantics.readConstraint( constraintRule ) ); } else if ( rule instanceof StoreIndexDescriptor ) { CapableIndexDescriptor index = indexProviderMap.withCapabilities( (StoreIndexDescriptor) rule ); indexDescriptorById.put( index.getId(), index ); SchemaDescriptor schemaDescriptor = index.schema(); indexDescriptors.put( schemaDescriptor, index ); indexDescriptorsByName.put( rule.getName(), index ); for ( int entityTokenId : schemaDescriptor.getEntityTokenIds() ) { Set<CapableIndexDescriptor> forLabel = indexDescriptorsByLabel.getIfAbsentPut( entityTokenId, HashSet::new ); forLabel.add( index ); } for ( int propertyId : index.schema().getPropertyIds() ) { List<CapableIndexDescriptor> indexesForProperty = indexByProperty.getIfAbsentPut( propertyId, ArrayList::new ); indexesForProperty.add( index ); } } }
ConstraintRule( long id, ConstraintDescriptor descriptor, Long ownedIndex, String name ) { this.id = id; this.descriptor = descriptor; this.ownedIndex = ownedIndex; this.name = SchemaRule.nameOrDefault( name, "constraint_" + id ); }
private void changeSchemaRule( SchemaRule rule, SchemaRule updatedRule ) { //Read the current record RecordProxy<SchemaRecord,SchemaRule> change = recordChangeSet.getSchemaRuleChanges() .getOrLoad( rule.getId(), rule ); SchemaRecord records = change.forReadingData(); //Register the change of the record RecordProxy<SchemaRecord,SchemaRule> recordChange = recordChangeSet.getSchemaRuleChanges() .setRecord( rule.getId(), records, updatedRule ); SchemaRecord dynamicRecords = recordChange.forChangingData(); //Update the record dynamicRecords.setDynamicRecords( schemaStore.allocateFrom( updatedRule ) ); }
@Test public void rulesCreatedWithNullNameMustRetainComputedNameAfterDeserialisation() throws Exception { assertThat( serialiseAndDeserialise( forLabel( LABEL_ID, PROPERTY_ID_1 ).withId( RULE_ID ) ).getName(), is( "index_1" ) ); assertThat( serialiseAndDeserialise( uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ).withIds( RULE_ID_2, RULE_ID ) ).getName(), is( "index_2" ) ); assertThat( serialiseAndDeserialise( forLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ).withId( RULE_ID ) ).getName(), is( "index_1" ) ); assertThat( serialiseAndDeserialise( uniqueForLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ).withIds( RULE_ID_2, RULE_ID ) ).getName(), is( "index_2" ) ); assertThat( serialiseAndDeserialise( forLabel( LABEL_ID, IntStream.range(1, 200).toArray() ).withId( RULE_ID ) ).getName(), is( "index_1" ) ); String name = null; assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID, ConstraintDescriptorFactory.existsForLabel( LABEL_ID, PROPERTY_ID_1 ), name ) ).getName(), is( "constraint_1" ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ), RULE_ID, name ) ).getName(), is( "constraint_2" ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.nodeKeyForLabel( LABEL_ID, PROPERTY_ID_1 ), RULE_ID, name ) ).getName(), is( "constraint_2" ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.existsForRelType( REL_TYPE_ID, PROPERTY_ID_1 ), name ) ).getName(), is( "constraint_2" ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID, ConstraintDescriptorFactory.existsForLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ), name ) ).getName(), is( "constraint_1" ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.existsForRelType( REL_TYPE_ID, PROPERTY_ID_1, PROPERTY_ID_2 ), name ) ).getName(), is( "constraint_2" ) ); }
void createSchemaRule( SchemaRule schemaRule ) { for ( DynamicRecord change : recordChangeSet.getSchemaRuleChanges() .create( schemaRule.getId(), schemaRule ) .forChangingData() ) { change.setInUse( true ); change.setCreated(); } }
@Test public void rulesCreatedWithNameMustRetainGivenNameAfterDeserialisation() throws Exception { String name = "custom_rule"; assertThat( serialiseAndDeserialise( namedForLabel( name, LABEL_ID, PROPERTY_ID_1 ).withId( RULE_ID ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( namedUniqueForLabel( name, LABEL_ID, PROPERTY_ID_1 ).withIds( RULE_ID_2, RULE_ID ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( namedForLabel( name, LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ).withId( RULE_ID ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( namedUniqueForLabel( name, LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ).withIds( RULE_ID_2, RULE_ID ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( namedForLabel( name, LABEL_ID, IntStream.range(1, 200).toArray() ).withId( RULE_ID ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID, ConstraintDescriptorFactory.existsForLabel( LABEL_ID, PROPERTY_ID_1 ), name ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ), RULE_ID, name ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.nodeKeyForLabel( LABEL_ID, PROPERTY_ID_1 ), RULE_ID, name ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.existsForRelType( REL_TYPE_ID, PROPERTY_ID_1 ), name ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID, ConstraintDescriptorFactory.existsForLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ), name ) ).getName(), is( name ) ); assertThat( serialiseAndDeserialise( ConstraintRule.constraintRule( RULE_ID_2, ConstraintDescriptorFactory.existsForRelType( REL_TYPE_ID, PROPERTY_ID_1, PROPERTY_ID_2 ), name ) ).getName(), is( name ) ); }
void dropSchemaRule( SchemaRule rule ) { RecordProxy<SchemaRecord, SchemaRule> change = recordChangeSet.getSchemaRuleChanges().getOrLoad( rule.getId(), rule ); SchemaRecord records = change.forChangingData(); for ( DynamicRecord record : records ) { record.setInUse( false ); } records.setInUse( false ); }
void addSchemaRule( SchemaRule rule ) { if ( rule instanceof ConstraintRule ) { ConstraintRule constraintRule = (ConstraintRule) rule; constraintRuleById.put( constraintRule.getId(), constraintRule ); constraints.add( constraintSemantics.readConstraint( constraintRule ) ); } else if ( rule instanceof StoreIndexDescriptor ) { CapableIndexDescriptor index = indexProviderMap.withCapabilities( (StoreIndexDescriptor) rule ); indexDescriptorById.put( index.getId(), index ); SchemaDescriptor schemaDescriptor = index.schema(); indexDescriptors.put( schemaDescriptor, index ); indexDescriptorsByName.put( rule.getName(), index ); for ( int entityTokenId : schemaDescriptor.getEntityTokenIds() ) { Set<CapableIndexDescriptor> forLabel = indexDescriptorsByLabel.getIfAbsentPut( entityTokenId, HashSet::new ); forLabel.add( index ); } for ( int propertyId : index.schema().getPropertyIds() ) { List<CapableIndexDescriptor> indexesForProperty = indexByProperty.getIfAbsentPut( propertyId, ArrayList::new ); indexesForProperty.add( index ); } } }
@Test public void addRemoveIndexes() { Collection<SchemaRule> rules = asList( hans, witch, gretel, robot ); SchemaCache cache = new SchemaCache( new ConstraintSemantics(), rules, IndexProviderMap.EMPTY ); StoreIndexDescriptor rule1 = newIndexRule( 10, 11, 12 ); StoreIndexDescriptor rule2 = newIndexRule( 13, 14, 15 ); cache.addSchemaRule( rule1 ); cache.addSchemaRule( rule2 ); cache.removeSchemaRule( hans.getId() ); cache.removeSchemaRule( witch.getId() ); assertEquals( asSet( gretel, rule1, rule2 ), Iterables.asSet( cache.indexDescriptors() ) ); assertEquals( asSet( robot ), Iterables.asSet( cache.constraintRules() ) ); }
@Test public void shouldDropUniquenessConstraintWhereConstraintRecordIsMissing() throws Exception { // given try ( Transaction tx = db.beginTx() ) { db.schema().constraintFor( label ).assertPropertyIsUnique( key ).create(); tx.success(); } // when intentionally breaking the schema by setting the backing index rule to unused RecordStorageEngine storageEngine = db.getDependencyResolver().resolveDependency( RecordStorageEngine.class ); SchemaStore schemaStore = storageEngine.testAccessNeoStores().getSchemaStore(); SchemaRule indexRule = single( filter( rule -> rule instanceof ConstraintRule, schemaStore.loadAllSchemaRules() ) ); setSchemaRecordNotInUse( schemaStore, indexRule.getId() ); // At this point the SchemaCache doesn't know about this change so we have to reload it storageEngine.loadSchemaCache(); try ( Transaction tx = db.beginTx() ) { // We don't use single() here, because it is okay for the schema cache reload to clean up after us. db.schema().getConstraints( label ).forEach( ConstraintDefinition::drop ); db.schema().getIndexes( label ).forEach( IndexDefinition::drop ); tx.success(); } // then try ( Transaction ignore = db.beginTx() ) { assertFalse( db.schema().getConstraints().iterator().hasNext() ); assertFalse( db.schema().getIndexes().iterator().hasNext() ); } }
@Test public void shouldDropUniquenessConstraintWithBackingIndexNotInUse() { // given try ( Transaction tx = db.beginTx() ) { db.schema().constraintFor( label ).assertPropertyIsUnique( key ).create(); tx.success(); } // when intentionally breaking the schema by setting the backing index rule to unused RecordStorageEngine storageEngine = db.getDependencyResolver().resolveDependency( RecordStorageEngine.class ); SchemaStore schemaStore = storageEngine.testAccessNeoStores().getSchemaStore(); SchemaRule indexRule = single( filter( rule -> rule instanceof StoreIndexDescriptor, schemaStore.loadAllSchemaRules() ) ); setSchemaRecordNotInUse( schemaStore, indexRule.getId() ); // At this point the SchemaCache doesn't know about this change so we have to reload it storageEngine.loadSchemaCache(); try ( Transaction tx = db.beginTx() ) { single( db.schema().getConstraints( label ).iterator() ).drop(); tx.success(); } // then try ( Transaction ignore = db.beginTx() ) { assertFalse( db.schema().getConstraints().iterator().hasNext() ); assertFalse( db.schema().getIndexes().iterator().hasNext() ); } }
SchemaStore schemaStore = storageEngine.testAccessNeoStores().getSchemaStore(); SchemaRule constraintRule = single( filter( rule -> rule instanceof ConstraintRule, schemaStore.loadAllSchemaRules() ) ); setSchemaRecordNotInUse( schemaStore, constraintRule.getId() ); SchemaRule indexRule = single( filter( rule -> rule instanceof StoreIndexDescriptor, schemaStore.loadAllSchemaRules() ) ); setOwnerNull( schemaStore, (StoreIndexDescriptor) indexRule );
public List<DynamicRecord> allocateFrom( SchemaRule rule ) { List<DynamicRecord> records = new ArrayList<>(); DynamicRecord record = getRecord( rule.getId(), nextRecord(), CHECK ); DynamicRecordAllocator recordAllocator = new ReusableRecordsCompositeAllocator( singleton( record ), this ); allocateRecordsFromBytes( records, SchemaRuleSerialization.serialize( rule ), recordAllocator ); return records; }
private void changeSchemaRule( SchemaRule rule, SchemaRule updatedRule ) { //Read the current record RecordProxy<SchemaRecord,SchemaRule> change = recordChangeSet.getSchemaRuleChanges() .getOrLoad( rule.getId(), rule ); SchemaRecord records = change.forReadingData(); //Register the change of the record RecordProxy<SchemaRecord,SchemaRule> recordChange = recordChangeSet.getSchemaRuleChanges() .setRecord( rule.getId(), records, updatedRule ); SchemaRecord dynamicRecords = recordChange.forChangingData(); //Update the record dynamicRecords.setDynamicRecords( schemaStore.allocateFrom( updatedRule ) ); }