Search in sources :

Example 26 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class MessageFieldArgument method apply.

@Override
@SuppressWarnings("unchecked")
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
    if (message.has(field)) {
        switch(field.getType()) {
            case BOOL:
                {
                    boolean value = message.get(field);
                    if (type == Types.BOOLEAN || type == Types.BIT) {
                        statement.setBoolean(position, value);
                    } else {
                        statement.setInt(position, value ? 1 : 0);
                    }
                    break;
                }
            case BYTE:
                {
                    statement.setByte(position, message.get(field));
                    break;
                }
            case I16:
                {
                    statement.setShort(position, message.get(field));
                    break;
                }
            case I32:
                {
                    if (type == Types.TIMESTAMP) {
                        Timestamp timestamp = new Timestamp(1000L * (int) message.get(field));
                        statement.setTimestamp(position, timestamp);
                    } else {
                        statement.setInt(position, message.get(field));
                    }
                    break;
                }
            case I64:
                {
                    if (type == Types.TIMESTAMP) {
                        Timestamp timestamp = new Timestamp(message.get(field));
                        statement.setTimestamp(position, timestamp);
                    } else {
                        statement.setLong(position, message.get(field));
                    }
                    break;
                }
            case DOUBLE:
                {
                    statement.setDouble(position, message.get(field));
                    break;
                }
            case STRING:
                {
                    statement.setString(position, message.get(field));
                    break;
                }
            case BINARY:
                {
                    Binary binary = message.get(field);
                    switch(type) {
                        case Types.BINARY:
                        case Types.VARBINARY:
                            {
                                statement.setBytes(position, binary.get());
                                break;
                            }
                        case Types.BLOB:
                            {
                                statement.setBlob(position, binary.getInputStream());
                                break;
                            }
                        case Types.CHAR:
                        case Types.VARCHAR:
                        case Types.NCHAR:
                        case Types.NVARCHAR:
                            {
                                statement.setString(position, binary.toBase64());
                                break;
                            }
                        default:
                            throw new ResultSetException("Unknown binary field type: " + type + " for " + field, null, ctx);
                    }
                    break;
                }
            case ENUM:
                {
                    PEnumValue value = message.get(field);
                    statement.setInt(position, value.asInteger());
                    break;
                }
            case MESSAGE:
                {
                    PMessage value = message.get(field);
                    switch(type) {
                        case Types.BINARY:
                        case Types.VARBINARY:
                            {
                                ByteArrayOutputStream out = new ByteArrayOutputStream();
                                try {
                                    BINARY.serialize(out, value);
                                    statement.setBytes(position, out.toByteArray());
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        case Types.BLOB:
                            {
                                ByteArrayOutputStream out = new ByteArrayOutputStream();
                                try {
                                    BINARY.serialize(out, value);
                                    statement.setBlob(position, new ByteArrayInputStream(out.toByteArray()));
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        case Types.CHAR:
                        case Types.VARCHAR:
                        case Types.NCHAR:
                        case Types.NVARCHAR:
                            {
                                StringWriter writer = new StringWriter();
                                try {
                                    JSON.serialize(new PrintWriter(writer), value);
                                    statement.setString(position, writer.getBuffer().toString());
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        case Types.CLOB:
                            {
                                StringWriter writer = new StringWriter();
                                try {
                                    JSON.serialize(new PrintWriter(writer), value);
                                    statement.setClob(position, new StringReader(writer.getBuffer().toString()));
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        default:
                            throw new ResultSetException("Unknown message field type: " + type + " for " + field, null, ctx);
                    }
                    break;
                }
            default:
                throw new ResultSetException("Unhandled field type in SQL: " + field, null, ctx);
        }
    } else {
        statement.setNull(position, type);
    }
}
Also used : ResultSetException(org.jdbi.v3.core.result.ResultSetException) StringWriter(java.io.StringWriter) ByteArrayInputStream(java.io.ByteArrayInputStream) PMessage(net.morimekta.providence.PMessage) StringReader(java.io.StringReader) PEnumValue(net.morimekta.providence.PEnumValue) Binary(net.morimekta.util.Binary) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Timestamp(java.sql.Timestamp) PrintWriter(java.io.PrintWriter)

Example 27 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class MessageNamedArgumentFinder method find.

@Nonnull
@Override
@SuppressWarnings("unchecked")
public Optional<Argument> find(String name, StatementContext ctx) {
    if (!prefix.isEmpty()) {
        if (name.startsWith(prefix)) {
            name = name.substring(prefix.length());
        } else {
            return Optional.empty();
        }
    }
    String[] parts = name.split("[.]");
    PMessage leaf = message;
    PMessageDescriptor leafDescriptor = message.descriptor();
    for (int i = 0; i < parts.length - 1; ++i) {
        String part = parts[i];
        PField field = leafDescriptor.findFieldByName(part);
        if (field == null)
            return Optional.empty();
        if (field.getType() != PType.MESSAGE) {
            throw new IllegalArgumentException("");
        }
        leafDescriptor = (PMessageDescriptor) field.getDescriptor();
        if (leaf != null) {
            leaf = (PMessage) leaf.get(field.getId());
        }
    }
    String leafName = parts[parts.length - 1];
    PField field = leafDescriptor.findFieldByName(leafName);
    if (field != null) {
        if (leaf != null) {
            return Optional.of(new MessageFieldArgument(leaf, field, getColumnType(field)));
        }
        return Optional.of(new NullArgument(getColumnType(field)));
    }
    return Optional.empty();
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) NullArgument(org.jdbi.v3.core.argument.NullArgument) Nonnull(javax.annotation.Nonnull)

Example 28 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class OverrideConfigSupplier method buildOverrideConfig.

private static <Message extends PMessage<Message, Field>, Field extends PField> Message buildOverrideConfig(Message parent, Map<String, String> overrides, boolean strict) throws ProvidenceConfigException {
    PMessageBuilder<Message, Field> builder = parent.mutate();
    for (Map.Entry<String, String> override : overrides.entrySet()) {
        String[] path = override.getKey().split("[.]");
        String fieldName = lastFieldName(path);
        PMessageBuilder containedBuilder = builderForField(strict, builder, path);
        if (containedBuilder == null) {
            continue;
        }
        PField field = containedBuilder.descriptor().findFieldByName(fieldName);
        if (field == null) {
            if (strict) {
                throw new ProvidenceConfigException("No such field %s in %s [%s]", fieldName, containedBuilder.descriptor().getQualifiedName(), String.join(".", path));
            }
            continue;
        }
        if (UNDEFINED.equals(override.getValue())) {
            containedBuilder.clear(field.getId());
        } else {
            containedBuilder.set(field.getId(), readFieldValue(override.getKey(), override.getValue(), field.getDescriptor()));
        }
    }
    return builder.build();
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) PMessageBuilder(net.morimekta.providence.PMessageBuilder) PField(net.morimekta.providence.descriptor.PField) ImmutableMap(com.google.common.collect.ImmutableMap) TreeMap(java.util.TreeMap) Map(java.util.Map)

Example 29 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class ProvidenceConfigParser method parseDefinitionValue.

@SuppressWarnings("unchecked")
Object parseDefinitionValue(ProvidenceConfigContext context, Tokenizer tokenizer) throws IOException {
    Token token = tokenizer.expect("Start of def value");
    if (token.isReal()) {
        return Double.parseDouble(token.asString());
    } else if (token.isInteger()) {
        return Long.parseLong(token.asString());
    } else if (token.isStringLiteral()) {
        return token.decodeLiteral(strict);
    } else if (TRUE.equalsIgnoreCase(token.asString())) {
        return Boolean.TRUE;
    } else if (FALSE.equalsIgnoreCase(token.asString())) {
        return Boolean.FALSE;
    } else if (Token.B64.equals(token.asString())) {
        tokenizer.expectSymbol("binary data enclosing start", Token.kParamsStart);
        return Binary.fromBase64(tokenizer.readBinary(Token.kParamsEnd));
    } else if (Token.HEX.equals(token.asString())) {
        tokenizer.expectSymbol("binary data enclosing start", Token.kParamsStart);
        return Binary.fromHexString(tokenizer.readBinary(Token.kParamsEnd));
    } else if (token.isDoubleQualifiedIdentifier()) {
        // this may be an enum reference, must be
        // - package.EnumType.IDENTIFIER
        String id = token.asString();
        int l = id.lastIndexOf(Token.kIdentifierSep);
        try {
            PEnumDescriptor ed = registry.getEnumType(id.substring(0, l));
            PEnumValue val = ed.findByName(id.substring(l + 1));
            if (val == null && strict) {
                throw new TokenizerException(token, "Unknown %s value: %s", id.substring(0, l), id.substring(l + 1)).setLine(tokenizer.getLine());
            }
            // Note that unknown enum value results in null. Therefore we don't catch null values here.
            return val;
        } catch (IllegalArgumentException e) {
            // No such declared type.
            if (strict) {
                throw new TokenizerException(token, "Unknown enum identifier: %s", id.substring(0, l)).setLine(tokenizer.getLine());
            }
            consumeValue(context, tokenizer, token);
        } catch (ClassCastException e) {
            // Not an enum.
            throw new TokenizerException(token, "Identifier " + id + " does not reference an enum, from " + token.asString()).setLine(tokenizer.getLine());
        }
    } else if (token.isQualifiedIdentifier()) {
        // Message type.
        PMessageDescriptor descriptor;
        try {
            descriptor = registry.getMessageType(token.asString());
        } catch (IllegalArgumentException e) {
            // - strict mode: all types must be known.
            if (strict) {
                throw new TokenizerException(token, "Unknown declared type: %s", token.asString()).setLine(tokenizer.getLine());
            }
            consumeValue(context, tokenizer, token);
            return null;
        }
        PMessageBuilder builder = descriptor.builder();
        if (tokenizer.expectSymbol("message start or inherits", '{', ':') == ':') {
            token = tokenizer.expect("inherits reference");
            PMessage inheritsFrom = resolve(context, token, tokenizer, descriptor);
            if (inheritsFrom == null) {
                throw new TokenizerException(token, "Inheriting from null reference: %s", token.asString()).setLine(tokenizer.getLine());
            }
            builder.merge(inheritsFrom);
            tokenizer.expectSymbol("message start", '{');
        }
        return parseMessage(tokenizer, context, builder);
    } else {
        throw new TokenizerException(token, "Invalid define value " + token.asString()).setLine(tokenizer.getLine());
    }
    return null;
}
Also used : PMessageBuilder(net.morimekta.providence.PMessageBuilder) PMessage(net.morimekta.providence.PMessage) PEnumValue(net.morimekta.providence.PEnumValue) Token(net.morimekta.providence.serializer.pretty.Token) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor)

Example 30 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class GenericMethods method assertValueIntegrity.

@SuppressWarnings("unchecked")
private void assertValueIntegrity(PField expectedField, Object actualValue, Object expectedValue) {
    if (actualValue == null || expectedValue == null) {
        assertThat(expectedField.toString(), actualValue, is(expectedValue));
    } else if (actualValue instanceof PMessage && expectedValue instanceof PMessage) {
        assertFieldIntegrity((PMessage<?, ?>) actualValue, (PMessage<?, ?>) expectedValue);
    } else if (actualValue instanceof PEnumValue && expectedValue instanceof PEnumValue) {
        assertThat(expectedField.toString(), ((PEnumValue) actualValue).getId(), is(((PEnumValue) expectedValue).getId()));
    } else if (actualValue instanceof List && expectedValue instanceof List) {
        List<Object> actualList = (List) actualValue;
        List<Object> expectedList = (List) expectedValue;
        assertThat(expectedField.toString(), actualList, hasSize(expectedList.size()));
        for (int i = 0; i < actualList.size(); ++i) {
            assertValueIntegrity(expectedField, actualList.get(i), expectedList.get(i));
        }
    } else if (actualValue instanceof Set && expectedValue instanceof Set) {
        TreeSet<Object> actualSet = new TreeSet<>((Set<Object>) actualValue);
        TreeSet<Object> expectedSet = new TreeSet<>((Set<Object>) expectedValue);
        assertThat(expectedField.toString(), actualSet, hasSize(expectedSet.size()));
        while (actualSet.size() > 0) {
            assertValueIntegrity(expectedField, actualSet.pollFirst(), expectedSet.pollFirst());
        }
    } else if (actualValue instanceof Map && expectedValue instanceof Map) {
        Map actualMap = (Map) actualValue;
        Map expectedMap = (Map) expectedValue;
        assertValueIntegrity(expectedField, actualMap.keySet(), expectedMap.keySet());
        for (Object key : actualMap.keySet()) {
            if (key instanceof PEnumValue) {
                // Search for the enum with the same ID in the expected map keys.
                Object expectedKey = expectedMap.keySet().stream().filter(k -> ((PEnumValue) k).getId() == ((PEnumValue) key).getId()).findFirst().orElse(null);
                if (expectedKey == null) {
                    throw new AssertionError("No expected map key matching " + key);
                }
                assertValueIntegrity(expectedField, actualMap.get(key), expectedMap.get(expectedKey));
            } else if (key instanceof PMessage) {
                // The messages should sort identically.
                TreeSet<PMessage> actualKeys = new TreeSet<>(actualMap.keySet());
                TreeSet<PMessage> expectedKeys = new TreeSet<>(expectedMap.keySet());
                while (expectedKeys.size() > 0) {
                    PMessage actual = actualKeys.pollFirst();
                    PMessage expected = expectedKeys.pollFirst();
                    assertFieldIntegrity(actual, expected);
                    assertValueIntegrity(expectedField, actualMap.get(actual), expectedMap.get(expected));
                }
            } else {
                assertValueIntegrity(expectedField, actualMap.get(key), expectedMap.get(key));
            }
        }
    } else {
        assertThat(expectedField.toString(), actualValue, is(expectedValue));
    }
}
Also used : Config(com.hazelcast.config.Config) HazelcastInstance(com.hazelcast.core.HazelcastInstance) AfterClass(org.junit.AfterClass) GeneratorWatcher(net.morimekta.providence.testing.generator.GeneratorWatcher) Set(java.util.Set) Random(java.util.Random) TreeSet(java.util.TreeSet) PMessage(net.morimekta.providence.PMessage) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) Assert.assertThat(org.junit.Assert.assertThat) PField(net.morimekta.providence.descriptor.PField) List(java.util.List) IMap(com.hazelcast.core.IMap) Rule(org.junit.Rule) SimpleGeneratorWatcher(net.morimekta.providence.testing.generator.SimpleGeneratorWatcher) Map(java.util.Map) PEnumValue(net.morimekta.providence.PEnumValue) Is.is(org.hamcrest.core.Is.is) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) ProvidenceMatchers.equalToMessage(net.morimekta.providence.testing.ProvidenceMatchers.equalToMessage) Matchers.hasSize(org.hamcrest.Matchers.hasSize) PMessageBuilder(net.morimekta.providence.PMessageBuilder) Fairy(io.codearte.jfairy.Fairy) Before(org.junit.Before) Set(java.util.Set) TreeSet(java.util.TreeSet) PMessage(net.morimekta.providence.PMessage) TreeSet(java.util.TreeSet) PEnumValue(net.morimekta.providence.PEnumValue) List(java.util.List) IMap(com.hazelcast.core.IMap) Map(java.util.Map)

Aggregations

PMessage (net.morimekta.providence.PMessage)31 PField (net.morimekta.providence.descriptor.PField)20 Nonnull (javax.annotation.Nonnull)7 TokenizerException (net.morimekta.providence.serializer.pretty.TokenizerException)7 IOException (java.io.IOException)6 PEnumValue (net.morimekta.providence.PEnumValue)6 PServiceCall (net.morimekta.providence.PServiceCall)6 PServiceCallType (net.morimekta.providence.PServiceCallType)6 Token (net.morimekta.providence.serializer.pretty.Token)6 Map (java.util.Map)5 PApplicationException (net.morimekta.providence.PApplicationException)5 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)5 SerializerException (net.morimekta.providence.serializer.SerializerException)5 Binary (net.morimekta.util.Binary)5 ArrayList (java.util.ArrayList)4 PMessageBuilder (net.morimekta.providence.PMessageBuilder)4 PServiceMethod (net.morimekta.providence.descriptor.PServiceMethod)4 TMessage (org.apache.thrift.protocol.TMessage)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3