Package org.lilyproject.repository.api

Examples of org.lilyproject.repository.api.Record


     * Build a Put for inserting a new (blank) record into a Lily repository table.
     */
    public Put buildPut(Record newRecord, long version, FieldTypes fieldTypes, RecordEvent recordEvent,
            Set<BlobReference> referencedBlobs, Set<BlobReference> unReferencedBlobs, long occ) throws RecordException,
            InterruptedException, RepositoryException {
        Record dummyOriginalRecord = newRecord();
        Put put = new Put(newRecord.getId().toBytes());
        put.add(RecordCf.DATA.bytes, RecordColumn.DELETED.bytes, 1L, Bytes.toBytes(false));
        calculateRecordChanges(newRecord, dummyOriginalRecord, version, put, recordEvent, referencedBlobs,
                unReferencedBlobs, false, fieldTypes);
        put.add(RecordCf.DATA.bytes, RecordColumn.OCC.bytes, 1L, Bytes.toBytes(occ));
View Full Code Here


        RecordId recordId = record.getId();

        try {
            Pair<Record, byte[]> recordAndOcc = readWithOcc(record.getId(), null, null, fieldTypes);
            Record originalRecord = new UnmodifiableRecord(recordAndOcc.getV1());

            byte[] oldOccBytes = recordAndOcc.getV2();

            RecordEvent recordEvent = new RecordEvent();
            recordEvent.setType(Type.UPDATE);
            recordEvent.setTableName(getTableName());
            if (record.hasAttributes()) {
                recordEvent.getAttributes().putAll(record.getAttributes());
            }

            for (RecordUpdateHook hook : updateHooks) {
                hook.beforeUpdate(record, originalRecord, this, fieldTypes, recordEvent);
            }

            Record newRecord = record.cloneRecord();

            Put put = new Put(newRecord.getId().toBytes());
            Set<BlobReference> referencedBlobs = new HashSet<BlobReference>();
            Set<BlobReference> unReferencedBlobs = new HashSet<BlobReference>();
            long newVersion = originalRecord.getVersion() == null ? 1 : originalRecord.getVersion() + 1;

            // Check the mutation conditions.
            // It is important that we do this before checking if the record needs updating at all: otherwise,
            // another client might already have performed the update we intended to do, which is problematic
            // in cases like incrementing a counter (the counter should be updated twice, not once).
            Record conditionsResponse = MutationConditionVerifier.checkConditions(originalRecord, conditions, this,
                    record);
            if (conditionsResponse != null) {
                return conditionsResponse;
            }
View Full Code Here

    }

    private Record updateMutableFields(Record record, boolean latestRecordType, List<MutationCondition> conditions,
            FieldTypes fieldTypes) throws RepositoryException {

        Record newRecord = record.cloneRecord();

        RecordId recordId = record.getId();

        Long version = record.getVersion();
        if (version == null) {
            throw new InvalidRecordException("The version of the record cannot be null to update mutable fields",
                    record.getId());
        }

        try {
            Map<QName, Object> fields = getFieldsToUpdate(record);
            fields = filterMutableFields(fields, fieldTypes);

            Pair<Record, byte[]> recordAndOcc = readWithOcc(recordId, version, null, fieldTypes);
            Record originalRecord = new UnmodifiableRecord(recordAndOcc.getV1());

            byte[] oldOccBytes = recordAndOcc.getV2();

            Map<QName, Object> originalFields = filterMutableFields(originalRecord.getFields(), fieldTypes);

            Record originalNextRecord = null;
            Map<QName, Object> originalNextFields = null;
            try {
                originalNextRecord = read(recordId, version + 1, null, fieldTypes);
                originalNextFields = filterMutableFields(originalNextRecord.getFields(), fieldTypes);
            } catch (VersionNotFoundException e) {
                // There is no next version of the record
            }

            Put put = new Put(recordId.toBytes());
            Set<BlobReference> referencedBlobs = new HashSet<BlobReference>();
            Set<BlobReference> unReferencedBlobs = new HashSet<BlobReference>();

            RecordEvent recordEvent = new RecordEvent();
            recordEvent.setType(Type.UPDATE);
            recordEvent.setTableName(getTableName());
            recordEvent.setVersionUpdated(version);

            for (RecordUpdateHook hook : updateHooks) {
                hook.beforeUpdate(record, originalRecord, this, fieldTypes, recordEvent);
            }

            Set<Scope> changedScopes = calculateUpdateFields(record, fields, record.getMetadataMap(), originalFields,
                    originalRecord.getMetadataMap(), originalNextFields, version, put,
                    recordEvent, referencedBlobs, unReferencedBlobs, true, fieldTypes);
            for (BlobReference referencedBlob : referencedBlobs) {
                referencedBlob.setRecordId(recordId);
            }
            for (BlobReference unReferencedBlob : unReferencedBlobs) {
                unReferencedBlob.setRecordId(recordId);
            }

            if (!changedScopes.isEmpty()) {
                // Check the conditions after establishing that the record really needs updating, this makes the
                // conditional update operation idempotent.
                Record conditionsRecord = MutationConditionVerifier.checkConditions(originalRecord, conditions, this,
                        record);
                if (conditionsRecord != null) {
                    return conditionsRecord;
                }
View Full Code Here

    }

    @Test
    public void testCreateOrUpdate() throws Exception {
        RecordId id = idGenerator.newRecordId();
        Record record = repository.newRecord(id);
        record.setRecordType(recordType1.getName(), recordType1.getVersion());
        record.setField(fieldType1.getName(), "value1");

        Record resultRecord;
        resultRecord = repository.createOrUpdate(record);
        assertEquals(ResponseStatus.CREATED, resultRecord.getResponseStatus());
        resultRecord = repository.createOrUpdate(record);
        assertEquals(ResponseStatus.UP_TO_DATE, resultRecord.getResponseStatus());

        record.setField(fieldType1.getName(), "value2");
        resultRecord = repository.createOrUpdate(record);
        assertEquals(ResponseStatus.UPDATED, resultRecord.getResponseStatus());
        resultRecord = repository.createOrUpdate(record);
        assertEquals(ResponseStatus.UP_TO_DATE, resultRecord.getResponseStatus());
        resultRecord = repository.createOrUpdate(record);
        assertEquals(ResponseStatus.UP_TO_DATE, resultRecord.getResponseStatus());
    }
View Full Code Here

            // The existing record is read with authorization disabled, because when deleting a full record we
            // must make sure we can delete all the fields in it.
            Pair<Record, byte[]> recordAndOcc = readWithOcc(recordId, null, null, fieldTypes, true);
            recordAndOcc.getV1().setAttributes(attributes);
            Record originalRecord = new UnmodifiableRecord(recordAndOcc.getV1());

            // If the record contains any field with scope != non-versioned, do not allow to delete it if
            // authorization is active. This is because access to these fields will not be validated by the
            // first Put call below, and hence the clearData afterwards might fail, leaving us with a half-deleted
            // record.
            if (AuthorizationContextHolder.getCurrentContext() != null) {
                for (QName field : originalRecord.getFields().keySet()) {
                    if (fieldTypes.getFieldType(field).getScope() != Scope.NON_VERSIONED) {
                        throw new RepositoryException("Deleting records with versioned or versioned-mutable fields "
                                + "is not supported when authorization is active.");
                    }
                }
            }

            byte[] oldOcc = recordAndOcc.getV2();

            RecordEvent recordEvent = new RecordEvent();
            recordEvent.setType(Type.DELETE);
            recordEvent.setTableName(getTableName());
            if (attributes != null && !attributes.isEmpty()) {
                recordEvent.getAttributes().putAll(attributes);
            }

            for (RecordUpdateHook hook : updateHooks) {
                hook.beforeDelete(originalRecord, this, fieldTypes, recordEvent);
            }

            if (conditions != null) {
                Record conditionsRecord = MutationConditionVerifier.checkConditions(originalRecord, conditions, this,
                        null);
                if (conditionsRecord != null) {
                    return conditionsRecord;
                }
            }
View Full Code Here

        assertEquals(ResponseStatus.UP_TO_DATE, resultRecord.getResponseStatus());
    }

    @Test
    public void testUpdateMutableFieldsRecordType() throws Exception {
        Record record = repository.newRecord();
        record.setRecordType(recordType2.getName(), recordType2.getVersion());
        record.setField(fieldType4.getName(), 123);
        record.setField(fieldType5.getName(), true);
        record.setField(fieldType6.getName(), "value1");
        record = repository.create(record);

        // Updating versioned mutable fields should not require record type to be specified in the record
        record = repository.newRecord(record.getId());
        record.setVersion(1L);
        record.setField(fieldType6.getName(), "value2");
        record = repository.update(record, true, true);

        // Change record to a different record type
        RecordType recordTypeA = typeManager.newRecordType(new QName("testmut", "RTA"));
        recordTypeA.addFieldTypeEntry(fieldType4.getId(), false);
        recordTypeA.addFieldTypeEntry(fieldType5.getId(), false);
        recordTypeA.addFieldTypeEntry(fieldType6.getId(), false);
        recordTypeA = typeManager.createRecordType(recordTypeA);

        // Change the record type of the non-versioned scope (at the time of this writing, could not modify
        // just the record type of a record, hence also touching a field)
        record = repository.read(record.getId());
        record.setRecordType(recordTypeA.getName(), null);
        record.setField(fieldType4.getName(), 456);
        record = repository.update(record);
        record = repository.read(record.getId());
        assertEquals(recordTypeA.getName(), record.getRecordTypeName());

        // The record type of the versioned mutable scope should still be what it was before
        assertEquals(recordType2.getName(), record.getRecordTypeName(Scope.VERSIONED_MUTABLE));

        // Now update a versioned-mutable field without specifying a record type, would expect it to move
        // also to the new record type of the non-versioned scope.
        record = repository.newRecord(record.getId());
        record.setVersion(1L);
        record.setField(fieldType6.getName(), "value3");
        record = repository.update(record, true, true);
        assertEquals(recordTypeA.getName(), record.getRecordTypeName(Scope.VERSIONED_MUTABLE));
        assertEquals(recordTypeA.getVersion(), record.getRecordTypeVersion(Scope.VERSIONED_MUTABLE));
    }
View Full Code Here

        assertEquals(recordTypeA.getVersion(), record.getRecordTypeVersion(Scope.VERSIONED_MUTABLE));
    }

    @Test
    public void testReadMultipleRecords() throws Exception {
        Record record1 = createDefaultRecord();
        Record record2 = createDefaultRecord();
        Record record3 = createDefaultRecord();

        List<Record> readRecords = repository.read(Arrays.asList(record3.getId(), record1.getId()));

        assertEquals(2, readRecords.size());
        assertTrue(readRecords.contains(record1));
        assertTrue(readRecords.contains(record3));
View Full Code Here

        assertTrue(readRecords.isEmpty());
    }

    @Test
    public void testConditionalUpdate() throws Exception {
        Record record = createDefaultRecord();

        //
        // Single condition
        //
        record.setField(fieldType1.getName(), "value2");
        record = repository
                .update(record, Collections.singletonList(new MutationCondition(fieldType1.getName(), "xyz")));

        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
        assertEquals("value1", record.getField(fieldType1.getName()));

        // Check repository state was really not modified
        record = repository.read(record.getId());
        assertEquals("value1", record.getField(fieldType1.getName()));

        //
        // Multiple conditions
        //
        List<MutationCondition> conditions = new ArrayList<MutationCondition>();
        conditions.add(new MutationCondition(fieldType1.getName(), "value1")); // evals to true
        conditions.add(new MutationCondition(fieldType2.getName(), 123)); // evals to true
        conditions.add(new MutationCondition(fieldType3.getName(), false)); // evals to false

        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record, conditions);

        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
        assertEquals("value1", record.getField(fieldType1.getName()));

        // Check repository state was really not modified
        record = repository.read(record.getId());
        assertEquals("value1", record.getField(fieldType1.getName()));

        // reset record state
        record = createDefaultRecord();

        //
        // Not-equals condition
        //
        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(fieldType1.getName(), CompareOp.NOT_EQUAL, "value1")));

        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
        assertEquals("value1", record.getField(fieldType1.getName()));

        //
        // Other than equals conditions
        //
        for (CompareOp op : CompareOp.values()) {
            List<Integer> testValues = new ArrayList<Integer>();
            switch (op) {
                case LESS:
                    testValues.add(123);
                    testValues.add(122);
                    break;
                case LESS_OR_EQUAL:
                    testValues.add(122);
                    break;
                case EQUAL:
                    testValues.add(122);
                    testValues.add(124);
                    break;
                case NOT_EQUAL:
                    testValues.add(123);
                    break;
                case GREATER_OR_EQUAL:
                    testValues.add(124);
                    break;
                case GREATER:
                    testValues.add(123);
                    testValues.add(124);
            }

            for (Integer testValue : testValues) {
                record.setField(fieldType2.getName(), 999);
                record = repository.update(record,
                        Collections.singletonList(new MutationCondition(fieldType2.getName(), op, testValue)));

                assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
                assertEquals(123, record.getField(fieldType2.getName()));
            }
        }

        //
        // Allow missing fields
        //

        record.setField(fieldType1.getName(), "value2");
        // note that we're testing on field 1B!
        record = repository.update(record,
                Collections.singletonList(
                        new MutationCondition(fieldType1B.getName(), CompareOp.EQUAL, "whatever", true)));

        assertEquals(ResponseStatus.UPDATED, record.getResponseStatus());
        assertEquals("value2", record.getField(fieldType1.getName()));

        // reset record state
        record.setField(fieldType1.getName(), "value1");
        record = repository.update(record);

        //
        // Test for missing/present field
        //

        // Field MUST be missing
        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(fieldType1.getName(), CompareOp.EQUAL, null)));

        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
        assertEquals("value1", record.getField(fieldType1.getName()));

        // Field MUST NOT be missing (but can have whatever value) -- note that we test on field 1B!
        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(fieldType1B.getName(), CompareOp.NOT_EQUAL, null)));

        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
        assertEquals("value1", record.getField(fieldType1.getName()));

        // Same, successful case
        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(fieldType1.getName(), CompareOp.NOT_EQUAL, null)));

        assertEquals(ResponseStatus.UPDATED, record.getResponseStatus());
        assertEquals("value2", record.getField(fieldType1.getName()));

        // reset record state
        record.setField(fieldType1.getName(), "value1");
        record = repository.update(record);

        //
        // Supplied values differ from field type (classcastexception)
        //

        // TODO
//        record.setField(fieldType1.getName(), "value2");
//        try {
//            repository.update(record, Collections.singletonList(new MutationCondition(fieldType1.getName(), new Long(55))));
//            fail("Expected an exception");
//        } catch (ClassCastException e) {
//            // expected
//        }

        //
        // Test on system fields
        //

        final QName versionField = new QName("org.lilyproject.system", "version");

        // Create new record to be sure numbering starts from 1
        record = createDefaultRecord();

        record.setField(fieldType2.getName(), new Integer(55));
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(versionField, CompareOp.EQUAL, new Long(2))));
        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());

        record.setField(fieldType2.getName(), new Integer(55));
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(versionField, CompareOp.EQUAL, new Long(1))));
        assertEquals(ResponseStatus.UPDATED, record.getResponseStatus());
        assertEquals(new Long(2), record.getVersion());
        assertEquals(new Integer(55), record.getField(fieldType2.getName()));

        // Test behavior in case of null version
        record = repository.newRecord();
        record.setRecordType(recordType1.getName(), recordType1.getVersion());
        record.setField(fieldType1.getName(), "value1");
        record = repository.create(record);

        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(versionField, CompareOp.EQUAL, new Long(1))));
        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());

        record.setField(fieldType1.getName(), "value2");
        record = repository.update(record,
                Collections.singletonList(new MutationCondition(versionField, CompareOp.EQUAL, null)));
        assertEquals(ResponseStatus.UPDATED, record.getResponseStatus());

        //
        // Test conditional update on update of version-mutable fields
        //
        record = createDefaultRecord();

        record.setField(fieldType3.getName(), false);
        record = repository.update(record, true, true,
                Collections.singletonList(new MutationCondition(fieldType3.getName(), CompareOp.EQUAL, Boolean.FALSE)));
        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());

        record.setField(fieldType3.getName(), false);
        record = repository.update(record, true, true,
                Collections.singletonList(new MutationCondition(fieldType3.getName(), CompareOp.EQUAL, Boolean.TRUE)));
        assertEquals(ResponseStatus.UPDATED, record.getResponseStatus());

        // In case of versioned-mutable update, we can also add conditions on versioned and non-versioned fields
        conditions = new ArrayList<MutationCondition>();
        conditions.add(new MutationCondition(fieldType1.getName(), "value1")); // evals to true
        conditions.add(new MutationCondition(fieldType2.getName(), 124)); // evals to true

        record.setField(fieldType3.getName(), true);
        record = repository.update(record, true, true, conditions);
        assertEquals(ResponseStatus.CONFLICT, record.getResponseStatus());
    }
View Full Code Here

        }
    }

    public void linkField() throws Exception {
        // (1)
        Record record1 = table.newRecord();
        record1.setRecordType(new QName(BNS, "Book"));
        record1.setField(new QName(BNS, "title"), "Fishing 1");
        record1 = table.create(record1);

        // (2)
        Record record2 = table.newRecord();
        record2.setRecordType(new QName(BNS, "Book"));
        record2.setField(new QName(BNS, "title"), "Fishing 2");
        record2.setField(new QName(BNS, "sequel_to"), new Link(record1.getId()));
        record2 = table.create(record2);

        // (3)
        Link sequelToLink = (Link) record2.getField(new QName(BNS, "sequel_to"));
        RecordId sequelTo = sequelToLink.resolve(record2.getId(), repository.getIdGenerator());
        Record linkedRecord = table.read(sequelTo);
        System.out.println(linkedRecord.getField(new QName(BNS, "title")));
    }
View Full Code Here

        articleType.addFieldTypeEntry(authors.getId(), true);
        articleType.addFieldTypeEntry(body.getId(), true);
        articleType = typeManager.createRecordType(articleType);

        // (3)
        Record author1 = table.newRecord();
        author1.setRecordType(authorType.getName());
        author1.setField(name.getName(), "Author X");
        author1.setField(name.getName(), "author_x@authors.com");

        Record author2 = table.newRecord();
        author2.setRecordType(new QName(ANS, "author"));
        author2.setField(name.getName(), "Author Y");
        author2.setField(name.getName(), "author_y@authors.com");

        // (4)
        Record article = table.newRecord();
        article.setRecordType(articleType.getName());
        article.setField(new QName(ANS, "title"), "Title of the article");
        article.setField(new QName(ANS, "authors"), Lists.newArrayList(author1, author2));
        article.setField(new QName(ANS, "body"), "Body text of the article");
        article = table.create(article);

        PrintUtil.print(article, repository);
    }
View Full Code Here

TOP

Related Classes of org.lilyproject.repository.api.Record

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.