Search in sources :

Example 6 with StructField

use of com.google.cloud.spanner.Type.StructField in project java-spanner-jdbc by googleapis.

the class JdbcResultSetMetaDataTest method getFooTestResultSet.

private JdbcResultSet getFooTestResultSet(Statement statement) {
    List<Struct> rows = new ArrayList<>(4);
    for (int row = 1; row <= 4; row++) {
        Struct.Builder builder = Struct.newBuilder();
        for (TestColumn col : TEST_COLUMNS) {
            builder.set(col.name).to(getDefaultValue(col.type, row));
        }
        rows.add(builder.build());
    }
    StructField[] fields = new StructField[TEST_COLUMNS.size()];
    int index = 0;
    for (TestColumn col : TEST_COLUMNS) {
        fields[index] = StructField.of(col.name, col.type);
        index++;
    }
    ResultSet rs = ResultSets.forRows(Type.struct(fields), rows);
    return JdbcResultSet.of(statement, rs);
}
Also used : StructField(com.google.cloud.spanner.Type.StructField) ArrayList(java.util.ArrayList) ResultSet(com.google.cloud.spanner.ResultSet) Struct(com.google.cloud.spanner.Struct)

Example 7 with StructField

use of com.google.cloud.spanner.Type.StructField in project jans by JanssenProject.

the class SpannerFilterConverter method buildVariableExpression.

private Expression buildVariableExpression(TableMapping tableMapping, String attributeName, Object attribyteValue, Map<String, ValueWithStructField> queryParameters) throws SearchException {
    StructField structField = getStructField(tableMapping, attributeName);
    String usedAttributeName = attributeName;
    int idx = 0;
    while (queryParameters.containsKey(usedAttributeName) && (idx < 100)) {
        usedAttributeName = attributeName + Integer.toString(idx++);
    }
    queryParameters.put(usedAttributeName, new ValueWithStructField(attribyteValue, structField));
    return new UserVariable(usedAttributeName);
}
Also used : ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField) StructField(com.google.cloud.spanner.Type.StructField) UserVariable(net.sf.jsqlparser.expression.UserVariable) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField)

Example 8 with StructField

use of com.google.cloud.spanner.Type.StructField in project jans by JanssenProject.

the class SpannerOperationServiceImpl method getAttributeDataList.

private List<AttributeData> getAttributeDataList(String objectClass, ResultSet resultSet, boolean skipDn) throws EntryConvertationException {
    try {
        if ((resultSet == null)) {
            return null;
        }
        if (!resultSet.next()) {
            return null;
        }
        List<AttributeData> result = new ArrayList<AttributeData>();
        // TODO: Include child table columns
        Set<String> nullableColumns = connectionProvider.getTableNullableColumns(objectClass);
        List<StructField> structFields = resultSet.getType().getStructFields();
        int columnsCount = resultSet.getColumnCount();
        for (int i = 0; i < columnsCount; i++) {
            StructField structField = structFields.get(i);
            String attributeName = structField.getName();
            Code columnTypeCode = structField.getType().getCode();
            boolean isNullable = nullableColumns.contains(attributeName.toLowerCase());
            if (SpannerOperationService.DOC_ID.equalsIgnoreCase(attributeName) || SpannerOperationService.ID.equalsIgnoreCase(attributeName)) {
                // Skip internal attributes
                continue;
            }
            if (skipDn && SpannerOperationService.DN.equalsIgnoreCase(attributeName)) {
                // Skip DN attribute
                continue;
            }
            Boolean multiValued = Boolean.FALSE;
            Object[] attributeValueObjects;
            if (resultSet.isNull(i)) {
                attributeValueObjects = NO_OBJECTS;
                if (isNullable) {
                    // Ignore columns with default NULL values
                    continue;
                }
            } else {
                if (Code.ARRAY == columnTypeCode) {
                    attributeValueObjects = convertDbArrayToValue(resultSet, structField.getType().getArrayElementType(), i, attributeName);
                    multiValued = Boolean.TRUE;
                } else if (Code.BOOL == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getBoolean(i) };
                } else if (Code.DATE == columnTypeCode) {
                    attributeValueObjects = new Object[] { com.google.cloud.Date.toJavaUtilDate(resultSet.getDate(i)) };
                } else if (Code.TIMESTAMP == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getTimestamp(i).toDate() };
                } else if (Code.INT64 == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getLong(i) };
                } else if (Code.NUMERIC == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getBigDecimal(i).longValue() };
                } else if (Code.STRING == columnTypeCode) {
                    Object value = resultSet.getString(i);
                    try {
                        value = com.google.cloud.Timestamp.parseTimestamp(value.toString());
                    } catch (Exception ex) {
                    }
                    attributeValueObjects = new Object[] { value };
                } else {
                    throw new EntryConvertationException(String.format("Column with name '%s' does not contain unsupported type '%s'", attributeName, columnTypeCode));
                }
            }
            unescapeValues(attributeValueObjects);
            AttributeData tmpAttribute = new AttributeData(attributeName, attributeValueObjects, multiValued);
            if (multiValued != null) {
                tmpAttribute.setMultiValued(multiValued);
            }
            result.add(tmpAttribute);
        }
        return result;
    } catch (SpannerException ex) {
        throw new EntryConvertationException("Failed to convert entry!", ex);
    }
}
Also used : ArrayList(java.util.ArrayList) Code(com.google.cloud.spanner.Type.Code) DeleteException(io.jans.orm.exception.operation.DeleteException) IncompatibleTypeException(io.jans.orm.exception.operation.IncompatibleTypeException) PersistenceException(io.jans.orm.exception.operation.PersistenceException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) EntryConvertationException(io.jans.orm.exception.operation.EntryConvertationException) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) SpannerException(com.google.cloud.spanner.SpannerException) SearchException(io.jans.orm.exception.operation.SearchException) EntryNotFoundException(io.jans.orm.exception.operation.EntryNotFoundException) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField) StructField(com.google.cloud.spanner.Type.StructField) EntryConvertationException(io.jans.orm.exception.operation.EntryConvertationException) SpannerException(com.google.cloud.spanner.SpannerException) AttributeData(io.jans.orm.model.AttributeData)

Example 9 with StructField

use of com.google.cloud.spanner.Type.StructField in project jans by JanssenProject.

the class SpannerOperationServiceImpl method updateEntryImpl.

private boolean updateEntryImpl(TableMapping tableMapping, String key, List<AttributeDataModification> mods) throws PersistenceException {
    try {
        MessageDigest messageDigest = getMessageDigestInstance();
        Map<String, StructField> columTypes = tableMapping.getColumTypes();
        WriteBuilder mutationBuilder = Mutation.newInsertOrUpdateBuilder(tableMapping.getTableName()).set(SpannerOperationService.DOC_ID).to(key);
        List<Mutation> mutations = new LinkedList<>();
        for (AttributeDataModification attributeMod : mods) {
            AttributeData attribute = attributeMod.getAttribute();
            AttributeModificationType type = attributeMod.getModificationType();
            String attributeName = attribute.getName();
            StructField attributeType = columTypes.get(attributeName.toLowerCase());
            // If column not inside table we should check if there is child table
            if (attributeType == null) {
                TableMapping childTableMapping = connectionProvider.getChildTableMappingByKey(key, tableMapping, attributeName);
                if (childTableMapping == null) {
                    throw new PersistenceException(String.format("Failed to update entry. Column '%s' is undefined", attributeName));
                }
                Map<String, StructField> childColumTypes = childTableMapping.getColumTypes();
                StructField childAttributeType = childColumTypes.get(attributeName.toLowerCase());
                // Build Mutation for child table
                Map<String, Object> oldValues = null;
                if ((attributeMod.getOldAttribute() != null) && (attributeMod.getOldAttribute().getValues() != null)) {
                    oldValues = new HashMap<>();
                    for (Object oldValue : attributeMod.getOldAttribute().getValues()) {
                        String dictDocId = getStringUniqueKey(messageDigest, oldValue);
                        oldValues.put(dictDocId, oldValue);
                    }
                }
                if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type) || (AttributeModificationType.REPLACE == type)) {
                    for (Object value : attribute.getValues()) {
                        WriteBuilder childMutationBuilder = Mutation.newInsertOrUpdateBuilder(childTableMapping.getTableName());
                        String dictDocId = getStringUniqueKey(messageDigest, value);
                        childMutationBuilder.set(SpannerOperationService.DOC_ID).to(key).set(SpannerOperationService.DICT_DOC_ID).to(dictDocId);
                        setMutationBuilderValue(childMutationBuilder, childAttributeType, value);
                        mutations.add(childMutationBuilder.build());
                        if (oldValues != null) {
                            oldValues.remove(dictDocId);
                        }
                    }
                } else if (AttributeModificationType.REMOVE == type) {
                    // Build Mutation for child table
                    com.google.cloud.spanner.KeySet.Builder keySetBuilder = KeySet.newBuilder();
                    for (Object value : attribute.getValues()) {
                        String dictDocId = getStringUniqueKey(messageDigest, value);
                        keySetBuilder.addKey(Key.of(key, dictDocId));
                    }
                    Mutation childMutation = Mutation.delete(childTableMapping.getTableName(), keySetBuilder.build());
                    mutations.add(childMutation);
                } else {
                    throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
                }
                if ((oldValues != null) && (oldValues.size() > 0)) {
                    com.google.cloud.spanner.KeySet.Builder keySetBuilder = KeySet.newBuilder();
                    for (String removeDictDocId : oldValues.keySet()) {
                        keySetBuilder.addKey(Key.of(key, removeDictDocId));
                    }
                    Mutation childMutation = Mutation.delete(childTableMapping.getTableName(), keySetBuilder.build());
                    mutations.add(childMutation);
                }
            } else {
                if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type) || (AttributeModificationType.REPLACE == type)) {
                    setMutationBuilderValue(mutationBuilder, attributeType, attribute.getValues());
                } else if (AttributeModificationType.REMOVE == type) {
                    removeMutationBuilderValue(mutationBuilder, attribute, attributeType);
                } else {
                    throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
                }
            }
        }
        mutations.add(0, mutationBuilder.build());
        databaseClient.write(mutations);
        return true;
    } catch (SpannerException | IllegalStateException ex) {
        throw new PersistenceException("Failed to update entry", ex);
    }
}
Also used : AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) WriteBuilder(com.google.cloud.spanner.Mutation.WriteBuilder) Builder(com.google.cloud.spanner.Statement.Builder) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField) StructField(com.google.cloud.spanner.Type.StructField) MessageDigest(java.security.MessageDigest) KeySet(com.google.cloud.spanner.KeySet) TableMapping(io.jans.orm.cloud.spanner.model.TableMapping) LinkedList(java.util.LinkedList) AttributeDataModification(io.jans.orm.model.AttributeDataModification) WriteBuilder(com.google.cloud.spanner.Mutation.WriteBuilder) PersistenceException(io.jans.orm.exception.operation.PersistenceException) Mutation(com.google.cloud.spanner.Mutation) SpannerException(com.google.cloud.spanner.SpannerException) AttributeData(io.jans.orm.model.AttributeData)

Example 10 with StructField

use of com.google.cloud.spanner.Type.StructField in project jans by JanssenProject.

the class SpannerConnectionProvider method loadTableMetaData.

private void loadTableMetaData() {
    LOG.info("Scanning DB metadata...");
    long takes = System.currentTimeMillis();
    try (ResultSet resultSet = executeQuery(QUERY_PARENT_TABLE)) {
        if (resultSet.next()) {
            int tableNameIdx = resultSet.getColumnIndex("TABLE_NAME");
            int parentTableNameIdx = resultSet.getColumnIndex("PARENT_TABLE_NAME");
            do {
                String parentTableName = resultSet.getString(parentTableNameIdx);
                String tableName = resultSet.getString(tableNameIdx);
                Set<String> childAttributes;
                if (tableChildAttributesMap.containsKey(parentTableName)) {
                    childAttributes = tableChildAttributesMap.get(parentTableName);
                } else {
                    childAttributes = new HashSet<>();
                    tableChildAttributesMap.put(parentTableName, childAttributes);
                }
                if (tableName.startsWith(parentTableName + "_")) {
                    tableName = tableName.substring(parentTableName.length() + 1);
                }
                childAttributes.add(tableName);
            } while (resultSet.next());
        }
    } catch (SpannerException ex) {
        throw new ConnectionException("Failed to get database metadata", ex);
    }
    LOG.debug("Build child attributes map: '{}'.", tableChildAttributesMap);
    HashMap<String, Type> typeMap = buildSpannerTypesMap();
    try (ResultSet resultSet = executeQuery(QUERY_TABLE_SCHEMA)) {
        if (resultSet.next()) {
            int tableNameIdx = resultSet.getColumnIndex("TABLE_NAME");
            int columnNameIdx = resultSet.getColumnIndex("COLUMN_NAME");
            int spannerTypeIdx = resultSet.getColumnIndex("SPANNER_TYPE");
            int isNullableIdx = resultSet.getColumnIndex("IS_NULLABLE");
            do {
                String tableName = resultSet.getString(tableNameIdx);
                String columnName = resultSet.getString(columnNameIdx);
                String spannerType = resultSet.getString(spannerTypeIdx);
                String isNullable = resultSet.getString(isNullableIdx);
                // Load table schema
                Map<String, StructField> tableColumns;
                if (tableColumnsMap.containsKey(tableName)) {
                    tableColumns = tableColumnsMap.get(tableName);
                } else {
                    tableColumns = new HashMap<>();
                    tableColumnsMap.put(tableName, tableColumns);
                }
                String comparebleType = toComparableType(spannerType);
                Type type = typeMap.get(comparebleType);
                if (type == null) {
                    throw new ConnectionException(String.format("Failed to parse SPANNER_TYPE: '%s'", spannerType));
                }
                tableColumns.put(columnName.toLowerCase(), StructField.of(columnName, type));
                // Check if column nullable
                Set<String> nullableColumns;
                if (tableNullableColumnsSet.containsKey(tableName)) {
                    nullableColumns = tableNullableColumnsSet.get(tableName);
                } else {
                    nullableColumns = new HashSet<>();
                    tableNullableColumnsSet.put(tableName, nullableColumns);
                }
                boolean nullable = "yes".equalsIgnoreCase(isNullable);
                if (nullable) {
                    nullableColumns.add(columnName.toLowerCase());
                }
            } while (resultSet.next());
        }
    } catch (SpannerException ex) {
        throw new ConnectionException("Failed to get database metadata", ex);
    }
    LOG.debug("Build table columns map: '{}'.", tableColumnsMap);
    takes = System.currentTimeMillis() - takes;
    LOG.info("Metadata scan finisehd in {} milliseconds", takes);
}
Also used : Type(com.google.cloud.spanner.Type) StructField(com.google.cloud.spanner.Type.StructField) ResultSet(com.google.cloud.spanner.ResultSet) SpannerException(com.google.cloud.spanner.SpannerException) ConnectionException(io.jans.orm.exception.operation.ConnectionException)

Aggregations

StructField (com.google.cloud.spanner.Type.StructField)11 ValueWithStructField (io.jans.orm.cloud.spanner.model.ValueWithStructField)7 TableMapping (io.jans.orm.cloud.spanner.model.TableMapping)5 SpannerException (com.google.cloud.spanner.SpannerException)4 ArrayList (java.util.ArrayList)4 ResultSet (com.google.cloud.spanner.ResultSet)3 PersistenceException (io.jans.orm.exception.operation.PersistenceException)3 SearchException (io.jans.orm.exception.operation.SearchException)3 AttributeData (io.jans.orm.model.AttributeData)3 LinkedList (java.util.LinkedList)3 Mutation (com.google.cloud.spanner.Mutation)2 WriteBuilder (com.google.cloud.spanner.Mutation.WriteBuilder)2 Struct (com.google.cloud.spanner.Struct)2 Code (com.google.cloud.spanner.Type.Code)2 MessageDigest (java.security.MessageDigest)2 KeySet (com.google.cloud.spanner.KeySet)1 Builder (com.google.cloud.spanner.Statement.Builder)1 Type (com.google.cloud.spanner.Type)1 KeyConversionException (io.jans.orm.exception.KeyConversionException)1 MappingException (io.jans.orm.exception.MappingException)1