Search in sources :

Example 1 with Field

use of io.cdap.cdap.spi.data.table.field.Field in project cdap by caskdata.

the class PostgreSqlStructuredTable method compareAndSwap.

@Override
public boolean compareAndSwap(Collection<Field<?>> keys, Field<?> oldValue, Field<?> newValue) throws InvalidFieldException, IOException {
    LOG.trace("Table {}: CompareAndSwap with keys {}, oldValue {}, newValue {}", tableSchema.getTableId(), keys, oldValue, newValue);
    fieldValidator.validatePrimaryKeys(keys, false);
    fieldValidator.validateField(oldValue);
    if (oldValue.getFieldType() != newValue.getFieldType()) {
        throw new IllegalArgumentException(String.format("Field types of oldValue (%s) and newValue (%s) are not the same", oldValue.getFieldType(), newValue.getFieldType()));
    }
    if (!oldValue.getName().equals(newValue.getName())) {
        throw new IllegalArgumentException(String.format("Trying to compare and swap different fields. Old Value = %s, New Value = %s", oldValue, newValue));
    }
    if (tableSchema.isPrimaryKeyColumn(oldValue.getName())) {
        throw new IllegalArgumentException("Cannot use compare and swap on a primary key field");
    }
    // First compare
    String readQuery = getReadQuery(keys, Collections.singleton(oldValue.getName()), true);
    try (PreparedStatement statement = connection.prepareStatement(readQuery)) {
        int index = 1;
        for (Field<?> key : keys) {
            setField(statement, key, index);
            index++;
        }
        LOG.trace("SQL statement: {}", statement);
        try (ResultSet resultSet = statement.executeQuery()) {
            if (resultSet.next()) {
                // Compare the value in the DB to oldValue
                Object colValue = resultSet.getObject(1);
                Field<?> dbValue = createField(oldValue.getName(), oldValue.getFieldType(), colValue);
                if (!oldValue.equals(dbValue)) {
                    return false;
                }
            } else {
                // There is no data for the field in the DB, hence oldValue should be null to continue
                if (oldValue.getValue() != null) {
                    return false;
                }
            }
        }
    } catch (SQLException e) {
        throw new IOException(String.format("Failed to read from table %s with keys %s", tableSchema.getTableId().getName(), keys), e);
    }
    // Then write
    Collection<Field<?>> fields = new HashSet<>(keys);
    fields.add(newValue);
    upsertInternal(fields);
    return true;
}
Also used : Field(io.cdap.cdap.spi.data.table.field.Field) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) IOException(java.io.IOException) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 2 with Field

use of io.cdap.cdap.spi.data.table.field.Field in project cdap by caskdata.

the class PostgreSqlStructuredTable method updateInternal.

private void updateInternal(Collection<Field<?>> fields) throws IOException {
    String sqlQuery = getUpdateSqlQuery(fields);
    try (PreparedStatement statement = connection.prepareStatement(sqlQuery)) {
        Map<Boolean, List<Field<?>>> lists = fields.stream().collect(Collectors.partitioningBy(field -> tableSchema.isPrimaryKeyColumn(field.getName())));
        int index = 1;
        // set field values to update
        for (Field<?> field : lists.get(false)) {
            setField(statement, field, index);
            index++;
        }
        // set field values in the WHERE clause
        for (Field<?> field : lists.get(true)) {
            setField(statement, field, index);
            index++;
        }
        LOG.trace("SQL statement: {}", statement);
        statement.executeUpdate();
    } catch (SQLException e) {
        throw new IOException(String.format("Failed to write to table %s with fields %s", tableSchema.getTableId().getName(), fields), e);
    }
}
Also used : IntStream(java.util.stream.IntStream) ConfigModule(io.cdap.cdap.common.guice.ConfigModule) Connection(java.sql.Connection) Inject(com.google.inject.Inject) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) LoggerFactory(org.slf4j.LoggerFactory) FieldValidator(io.cdap.cdap.spi.data.table.field.FieldValidator) Fields(io.cdap.cdap.spi.data.table.field.Fields) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) Map(java.util.Map) Field(io.cdap.cdap.spi.data.table.field.Field) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) SortOrder(io.cdap.cdap.spi.data.SortOrder) InvalidFieldException(io.cdap.cdap.spi.data.InvalidFieldException) Logger(org.slf4j.Logger) Collection(java.util.Collection) Set(java.util.Set) IOException(java.io.IOException) FieldType(io.cdap.cdap.spi.data.table.field.FieldType) PreparedStatement(java.sql.PreparedStatement) CloseableIterator(io.cdap.cdap.api.dataset.lib.CloseableIterator) Collectors(java.util.stream.Collectors) Injector(com.google.inject.Injector) AbstractCloseableIterator(io.cdap.cdap.api.dataset.lib.AbstractCloseableIterator) List(java.util.List) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) StructuredTable(io.cdap.cdap.spi.data.StructuredTable) Range(io.cdap.cdap.spi.data.table.field.Range) StringJoiner(java.util.StringJoiner) Statement(java.sql.Statement) Guice(com.google.inject.Guice) Optional(java.util.Optional) StructuredTableSchema(io.cdap.cdap.spi.data.table.StructuredTableSchema) Collections(java.util.Collections) ResultSetMetaData(java.sql.ResultSetMetaData) Joiner(com.google.common.base.Joiner) Types(java.sql.Types) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) ArrayList(java.util.ArrayList) List(java.util.List) IOException(java.io.IOException)

Example 3 with Field

use of io.cdap.cdap.spi.data.table.field.Field in project cdap by caskdata.

the class PostgreSqlStructuredTable method multiRead.

@Override
public Collection<StructuredRow> multiRead(Collection<? extends Collection<Field<?>>> multiKeys) throws InvalidFieldException, IOException {
    LOG.trace("Table {}: Read with multiple keys {}", tableSchema.getTableId(), multiKeys);
    if (multiKeys.isEmpty()) {
        return Collections.emptyList();
    }
    for (Collection<Field<?>> keys : multiKeys) {
        fieldValidator.validatePrimaryKeys(keys, false);
    }
    // Collapse values of each key
    Map<String, Set<Field<?>>> keyFields = new LinkedHashMap<>();
    multiKeys.stream().flatMap(Collection::stream).forEach(field -> keyFields.computeIfAbsent(field.getName(), k -> new LinkedHashSet<>()).add(field));
    try (PreparedStatement statement = prepareMultiReadQuery(keyFields)) {
        LOG.trace("SQL statement: {}", statement);
        Collection<StructuredRow> result = new ArrayList<>();
        try (ResultSet resultSet = statement.executeQuery()) {
            while (resultSet.next()) {
                result.add(resultSetToRow(resultSet));
            }
            return result;
        }
    } catch (SQLException e) {
        throw new IOException(String.format("Failed to read from table %s with multi keys %s", tableSchema.getTableId().getName(), multiKeys), e);
    }
}
Also used : HashSet(java.util.HashSet) ResultSet(java.sql.ResultSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) SQLException(java.sql.SQLException) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) IOException(java.io.IOException) LinkedHashMap(java.util.LinkedHashMap) Field(io.cdap.cdap.spi.data.table.field.Field) ResultSet(java.sql.ResultSet)

Example 4 with Field

use of io.cdap.cdap.spi.data.table.field.Field in project cdap by caskdata.

the class ArtifactStore method getApplicationClasses.

/**
 * Get all application classes that belong to the specified namespace.
 * Results are returned as a sorted map from artifact to application classes in that artifact.
 * Map entries are sorted by the artifact.
 *
 * @param namespace the namespace from which to get application classes
 * @return an unmodifiable map of artifact to a list of all application classes in that artifact.
 *         The map will never be null. If there are no application classes, an empty map will be returned.
 */
public SortedMap<ArtifactDescriptor, List<ApplicationClass>> getApplicationClasses(NamespaceId namespace) {
    return TransactionRunners.run(transactionRunner, context -> {
        SortedMap<ArtifactDescriptor, List<ApplicationClass>> result = Maps.newTreeMap();
        StructuredTable table = getTable(context, StoreDefinition.ArtifactStore.APP_DATA_TABLE);
        Collection<Field<?>> keys = Collections.singleton(Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace()));
        try (CloseableIterator<StructuredRow> iterator = table.scan(Range.singleton(keys), Integer.MAX_VALUE)) {
            while (iterator.hasNext()) {
                StructuredRow row = iterator.next();
                Map.Entry<ArtifactDescriptor, ApplicationClass> entry = extractApplicationClass(row);
                List<ApplicationClass> existingAppClasses = result.computeIfAbsent(entry.getKey(), k -> new ArrayList<>());
                existingAppClasses.add(entry.getValue());
            }
        }
        return Collections.unmodifiableSortedMap(result);
    });
}
Also used : StructuredTable(io.cdap.cdap.spi.data.StructuredTable) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) ApplicationClass(io.cdap.cdap.api.artifact.ApplicationClass) Field(io.cdap.cdap.spi.data.table.field.Field) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) SortedMap(java.util.SortedMap) AbstractMap(java.util.AbstractMap) TreeMap(java.util.TreeMap)

Example 5 with Field

use of io.cdap.cdap.spi.data.table.field.Field in project cdap by caskdata.

the class ArtifactStore method getApplicationClasses.

/**
 * Get all application classes that belong to the specified namespace of the specified classname.
 * Results are returned as a sorted map from artifact to application classes in that artifact.
 * Map entries are sorted by the artifact.
 *
 * @param namespace the namespace from which to get application classes
 * @param className the classname of application classes to get
 * @return an unmodifiable map of artifact the application classes in that artifact.
 *         The map will never be null. If there are no application classes, an empty map will be returned.
 */
public SortedMap<ArtifactDescriptor, ApplicationClass> getApplicationClasses(final NamespaceId namespace, final String className) {
    return TransactionRunners.run(transactionRunner, context -> {
        StructuredTable table = getTable(context, StoreDefinition.ArtifactStore.APP_DATA_TABLE);
        SortedMap<ArtifactDescriptor, ApplicationClass> result = Maps.newTreeMap();
        Collection<Field<?>> keys = ImmutableList.of(Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace()), Fields.stringField(StoreDefinition.ArtifactStore.CLASS_NAME_FIELD, className));
        try (CloseableIterator<StructuredRow> iterator = table.scan(Range.singleton(keys), Integer.MAX_VALUE)) {
            while (iterator.hasNext()) {
                StructuredRow row = iterator.next();
                Map.Entry<ArtifactDescriptor, ApplicationClass> entry = extractApplicationClass(row);
                result.put(entry.getKey(), entry.getValue());
            }
        }
        return Collections.unmodifiableSortedMap(result);
    });
}
Also used : Field(io.cdap.cdap.spi.data.table.field.Field) StructuredTable(io.cdap.cdap.spi.data.StructuredTable) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) ApplicationClass(io.cdap.cdap.api.artifact.ApplicationClass) Map(java.util.Map) SortedMap(java.util.SortedMap) AbstractMap(java.util.AbstractMap) TreeMap(java.util.TreeMap)

Aggregations

Field (io.cdap.cdap.spi.data.table.field.Field)72 StructuredRow (io.cdap.cdap.spi.data.StructuredRow)40 StructuredTable (io.cdap.cdap.spi.data.StructuredTable)33 ArrayList (java.util.ArrayList)33 Range (io.cdap.cdap.spi.data.table.field.Range)24 HashSet (java.util.HashSet)18 Map (java.util.Map)17 List (java.util.List)16 Nullable (javax.annotation.Nullable)16 CloseableIterator (io.cdap.cdap.api.dataset.lib.CloseableIterator)15 Collections (java.util.Collections)15 HashMap (java.util.HashMap)15 LinkedHashSet (java.util.LinkedHashSet)15 Set (java.util.Set)15 Fields (io.cdap.cdap.spi.data.table.field.Fields)14 Collection (java.util.Collection)14 LinkedHashMap (java.util.LinkedHashMap)14 Collectors (java.util.stream.Collectors)14 Optional (java.util.Optional)13 IOException (java.io.IOException)12