use of io.cdap.cdap.spi.data.InvalidFieldException in project cdap by cdapio.
the class PostgreSqlStructuredTable method scan.
@Override
public CloseableIterator<StructuredRow> scan(Field<?> index) throws InvalidFieldException, IOException {
LOG.trace("Table {}: Scan index {}", tableSchema.getTableId(), index);
fieldValidator.validateField(index);
if (!tableSchema.isIndexColumn(index.getName())) {
throw new InvalidFieldException(tableSchema.getTableId(), index.getName(), "is not an indexed column");
}
String sql = getReadQuery(Collections.singleton(index), null, false);
// We don't close the statement here because once it is closed, the result set is also closed.
try {
PreparedStatement statement = connection.prepareStatement(sql);
statement.setFetchSize(scanFetchSize);
setField(statement, index, 1);
LOG.trace("SQL statement: {}", statement);
ResultSet resultSet = statement.executeQuery();
return new ResultSetIterator(statement, resultSet, tableSchema);
} catch (SQLException e) {
throw new IOException(String.format("Failed to scan from table %s with index %s", tableSchema.getTableId().getName(), index), e);
}
}
use of io.cdap.cdap.spi.data.InvalidFieldException in project cdap by cdapio.
the class NoSqlStructuredTable method updateFieldsToBytes.
/**
* Updates fields in the row and converts to a {@link Put} to write to table. The primary key must be provided.
*
* @param fields the fields to update
* @return a PUT object
* @throws InvalidFieldException if primary keys are missing or the column is not in schema
*/
private Put updateFieldsToBytes(Collection<Field<?>> fields) throws InvalidFieldException {
Set<String> fieldNames = fields.stream().map(Field::getName).collect(Collectors.toSet());
if (!fieldNames.containsAll(schema.getPrimaryKeys())) {
throw new InvalidFieldException(schema.getTableId(), fields, String.format("Given fields %s does not contain all the " + "primary keys %s", fieldNames, schema.getPrimaryKeys()));
}
Set<String> primaryKeys = new HashSet<>(schema.getPrimaryKeys());
Collection<Field<?>> keyFields = fields.stream().filter(field -> primaryKeys.contains(field.getName())).collect(Collectors.toList());
byte[] primaryKey = convertKeyToBytes(keyFields, false);
Put put = new Put(primaryKey);
Row row = table.get(primaryKey);
Map<String, Field<?>> fieldMap = fields.stream().collect(Collectors.toMap(Field::getName, Function.identity()));
for (Map.Entry<byte[], byte[]> entry : row.getColumns().entrySet()) {
String columnName = Bytes.toString(entry.getKey());
if (!fieldMap.containsKey(columnName) || primaryKeys.contains(columnName)) {
put.add(entry.getKey(), entry.getValue());
} else {
put.add(entry.getKey(), fieldToBytes(fieldMap.get(columnName)));
}
}
return put;
}
use of io.cdap.cdap.spi.data.InvalidFieldException in project cdap by cdapio.
the class SpannerStructuredTable method scan.
@Override
public CloseableIterator<StructuredRow> scan(Field<?> index) throws InvalidFieldException {
fieldValidator.validateField(index);
if (!schema.isIndexColumn(index.getName())) {
throw new InvalidFieldException(schema.getTableId(), index.getName(), "is not an indexed column");
}
KeySet keySet = KeySet.singleKey(createKey(Collections.singleton(index)));
String indexName = SpannerStructuredTableAdmin.getIndexName(schema.getTableId(), index.getName());
ResultSet resultSet = transactionContext.readUsingIndex(schema.getTableId().getName(), indexName, keySet, schema.getFieldNames());
return new ResultSetIterator(schema, resultSet);
}
use of io.cdap.cdap.spi.data.InvalidFieldException in project cdap by cdapio.
the class SpannerStructuredTable method read.
@Override
public Optional<StructuredRow> read(Collection<Field<?>> keys, Collection<String> columns) throws InvalidFieldException {
if (columns.isEmpty()) {
throw new IllegalArgumentException("No column is specified to read");
}
fieldValidator.validatePrimaryKeys(keys, false);
Set<String> missingColumns = columns.stream().filter(f -> !schema.getFieldNames().contains(f)).collect(Collectors.toSet());
if (!missingColumns.isEmpty()) {
throw new IllegalArgumentException("Some columns do not exists in the table schema " + missingColumns);
}
// Adds all the keys to the result column as well. This is mirroring the PostgreSQL implementation.
Set<String> queryColumns = keys.stream().map(Field::getName).collect(Collectors.toSet());
queryColumns.addAll(columns);
Struct row = transactionContext.readRow(schema.getTableId().getName(), createKey(keys), queryColumns);
return Optional.ofNullable(row).map(r -> new SpannerStructuredRow(schema, r));
}
use of io.cdap.cdap.spi.data.InvalidFieldException in project cdap by cdapio.
the class SpannerStructuredTable method update.
@Override
public void update(Collection<Field<?>> fields) throws InvalidFieldException {
List<Field<?>> primaryKeyFields = new ArrayList<>();
List<Field<?>> updateFields = new ArrayList<>();
Set<String> fieldNames = new HashSet<>();
for (Field<?> field : fields) {
fieldValidator.validateField(field);
if (schema.isPrimaryKeyColumn(field.getName())) {
primaryKeyFields.add(field);
} else {
updateFields.add(field);
}
fieldNames.add(field.getName());
}
if (!fieldNames.containsAll(schema.getPrimaryKeys())) {
throw new InvalidFieldException(schema.getTableId(), fields, String.format("Given fields %s do not contain all the " + "primary keys %s", fieldNames, schema.getPrimaryKeys()));
}
String sql = "UPDATE " + escapeName(schema.getTableId().getName()) + " SET " + updateFields.stream().map(this::fieldToParam).collect(Collectors.joining(", ")) + " WHERE " + primaryKeyFields.stream().map(this::fieldToParam).collect(Collectors.joining(" AND "));
LOG.trace("Updating row: {}", sql);
Statement statement = fields.stream().reduce(Statement.newBuilder(sql), (builder, field) -> builder.bind(field.getName()).to(getValue(field)), (builder1, builder2) -> builder1).build();
transactionContext.executeUpdate(statement);
}
Aggregations