Search in sources :

Example 1 with PersistenceException

use of io.requery.PersistenceException in project requery by requery.

the class EntityWriter method updateAssociation.

@SuppressWarnings("unchecked")
private void updateAssociation(Cascade mode, E entity, EntityProxy<E> proxy, Attribute<E, ?> attribute) {
    switch(attribute.getCardinality()) {
        case ONE_TO_ONE:
            S value = (S) proxy.get(attribute, false);
            if (value != null) {
                Attribute<S, Object> mapped = Attributes.get(attribute.getMappedAttribute());
                EntityProxy<S> referred = context.proxyOf(value, true);
                referred.set(mapped, entity, PropertyState.MODIFIED);
                cascadeWrite(mode, value, referred);
            } else if (!stateless) {
                throw new PersistenceException("1-1 relationship can only be removed from the owning side");
            }
            break;
        case ONE_TO_MANY:
            Object relation = proxy.get(attribute, false);
            if (relation instanceof ObservableCollection) {
                ObservableCollection<S> collection = (ObservableCollection<S>) relation;
                CollectionChanges<?, S> changes = (CollectionChanges<?, S>) collection.observer();
                List<S> added = new ArrayList<>(changes.addedElements());
                List<S> removed = new ArrayList<>(changes.removedElements());
                changes.clear();
                for (S element : added) {
                    updateMappedAssociation(mode, element, attribute, entity);
                }
                for (S element : removed) {
                    updateMappedAssociation(Cascade.UPDATE, element, attribute, null);
                }
            } else if (relation instanceof Iterable) {
                Iterable<S> iterable = (Iterable<S>) relation;
                for (S added : iterable) {
                    updateMappedAssociation(mode, added, attribute, entity);
                }
            } else {
                throw new IllegalStateException("unsupported relation type " + relation);
            }
            break;
        case MANY_TO_MANY:
            final Class referencedClass = attribute.getReferencedClass();
            if (referencedClass == null) {
                throw new IllegalStateException("Invalid referenced class in " + attribute);
            }
            Type<?> referencedType = model.typeOf(referencedClass);
            QueryAttribute<S, Object> tKey = null;
            QueryAttribute<S, Object> uKey = null;
            for (Attribute a : referencedType.getAttributes()) {
                Class<?> referenced = a.getReferencedClass();
                if (referenced != null) {
                    if (tKey == null && entityClass.isAssignableFrom(referenced)) {
                        tKey = Attributes.query(a);
                    } else if (attribute.getElementClass() != null && attribute.getElementClass().isAssignableFrom(referenced)) {
                        uKey = Attributes.query(a);
                    }
                }
            }
            Objects.requireNotNull(tKey);
            Objects.requireNotNull(uKey);
            Attribute<E, Object> tRef = Attributes.get(tKey.getReferencedAttribute());
            Attribute<S, Object> uRef = Attributes.get(uKey.getReferencedAttribute());
            CollectionChanges<?, S> changes = null;
            relation = proxy.get(attribute, false);
            Iterable<S> addedElements = (Iterable<S>) relation;
            boolean isObservable = relation instanceof ObservableCollection;
            if (relation instanceof ObservableCollection) {
                ObservableCollection<S> collection = (ObservableCollection<S>) relation;
                changes = (CollectionChanges<?, S>) collection.observer();
                if (changes != null) {
                    addedElements = changes.addedElements();
                }
            }
            for (S added : addedElements) {
                S junction = (S) referencedType.getFactory().get();
                EntityProxy<S> junctionProxy = context.proxyOf(junction, false);
                EntityProxy<S> uProxy = context.proxyOf(added, false);
                if (attribute.getCascadeActions().contains(CascadeAction.SAVE)) {
                    cascadeWrite(mode, added, uProxy);
                }
                Object tValue = proxy.get(tRef, false);
                Object uValue = uProxy.get(uRef, false);
                junctionProxy.set(tKey, tValue, PropertyState.MODIFIED);
                junctionProxy.set(uKey, uValue, PropertyState.MODIFIED);
                Cascade cascade = isObservable && mode == Cascade.UPSERT ? Cascade.UPSERT : Cascade.INSERT;
                cascadeWrite(cascade, junction, null);
            }
            if (changes != null) {
                Object keyValue = proxy.get(tRef, false);
                for (S removed : changes.removedElements()) {
                    Object otherValue = context.proxyOf(removed, false).get(uRef);
                    Class<? extends S> removeType = (Class<? extends S>) referencedType.getClassType();
                    Supplier<? extends Scalar<Integer>> query = queryable.delete(removeType).where(tKey.equal(keyValue)).and(uKey.equal(otherValue));
                    int count = query.get().value();
                    if (count != 1) {
                        throw new RowCountException(entity.getClass(), 1, count);
                    }
                }
                changes.clear();
            }
            break;
        case MANY_TO_ONE:
        default:
            break;
    }
    context.read(type.getClassType()).refresh(entity, proxy, attribute);
}
Also used : QueryAttribute(io.requery.meta.QueryAttribute) Attribute(io.requery.meta.Attribute) UPDATE(io.requery.query.element.QueryType.UPDATE) ArrayList(java.util.ArrayList) CollectionChanges(io.requery.proxy.CollectionChanges) ObservableCollection(io.requery.util.ObservableCollection) PersistenceException(io.requery.PersistenceException)

Example 2 with PersistenceException

use of io.requery.PersistenceException in project requery by requery.

the class SchemaModifier method executeSql.

private void executeSql(Connection connection, QueryBuilder qb) {
    try (Statement statement = connection.createStatement()) {
        String sql = qb.toString();
        statementListeners.beforeExecuteUpdate(statement, sql, null);
        statement.execute(sql);
        statementListeners.afterExecuteUpdate(statement, 0);
    } catch (SQLException e) {
        throw new PersistenceException(e);
    }
}
Also used : SQLException(java.sql.SQLException) Statement(java.sql.Statement) PersistenceException(io.requery.PersistenceException)

Example 3 with PersistenceException

use of io.requery.PersistenceException in project requery by requery.

the class BatchUpdateOperation method evaluate.

@Override
public int[] evaluate(QueryElement<int[]> query) {
    int[] result = batchInStatement ? null : new int[length];
    try (Connection connection = configuration.getConnection()) {
        DefaultOutput generator = new DefaultOutput(configuration, query);
        String sql = generator.toSql();
        StatementListener listener = configuration.getStatementListener();
        try (PreparedStatement statement = prepare(sql, connection)) {
            for (int i = 0; i < length; i++) {
                E element = elements[i];
                parameterBinder.bindParameters(statement, element, null);
                if (batchInStatement) {
                    statement.addBatch();
                } else {
                    listener.beforeExecuteBatchUpdate(statement, sql);
                    result[i] = statement.executeUpdate();
                    listener.afterExecuteBatchUpdate(statement, result);
                    readGeneratedKeys(i, statement);
                }
            }
            if (batchInStatement) {
                listener.beforeExecuteBatchUpdate(statement, sql);
                result = statement.executeBatch();
                listener.afterExecuteBatchUpdate(statement, result);
                readGeneratedKeys(0, statement);
            }
        }
    } catch (BatchUpdateException e) {
        result = e.getUpdateCounts();
        if (result == null) {
            throw new PersistenceException(e);
        }
    } catch (SQLException e) {
        throw new PersistenceException(e);
    }
    return result;
}
Also used : SQLException(java.sql.SQLException) DefaultOutput(io.requery.sql.gen.DefaultOutput) Connection(java.sql.Connection) PersistenceException(io.requery.PersistenceException) PreparedStatement(java.sql.PreparedStatement) BatchUpdateException(java.sql.BatchUpdateException)

Example 4 with PersistenceException

use of io.requery.PersistenceException in project requery by requery.

the class EntityWriter method incrementVersion.

private void incrementVersion(EntityProxy<E> proxy) {
    if (versionAttribute != null && !hasSystemVersionColumn()) {
        Object version = proxy.get(versionAttribute);
        Class<?> type = versionAttribute.getClassType();
        if (type == Long.class || type == long.class) {
            if (version == null) {
                version = 1L;
            } else {
                Long value = (Long) version;
                version = value + 1;
            }
        } else if (type == Integer.class || type == int.class) {
            if (version == null) {
                version = 1;
            } else {
                Integer value = (Integer) version;
                version = value + 1;
            }
        } else if (type == Timestamp.class) {
            version = new Timestamp(System.currentTimeMillis());
        } else {
            throw new PersistenceException("Unsupported version type: " + versionAttribute.getClassType());
        }
        proxy.setObject(versionAttribute, version, PropertyState.MODIFIED);
    }
}
Also used : PersistenceException(io.requery.PersistenceException) Timestamp(java.sql.Timestamp)

Example 5 with PersistenceException

use of io.requery.PersistenceException in project requery by requery.

the class EntityReader method refresh.

private E refresh(E entity, EntityProxy<E> proxy, final Set<Attribute<E, ?>> attributes) {
    Predicate<Attribute<E, ?>> basicFilter = new Predicate<Attribute<E, ?>>() {

        @Override
        public boolean test(Attribute<E, ?> value) {
            return attributes.contains(value) && (!value.isAssociation() || value.isForeignKey());
        }
    };
    FilteringIterator<Attribute<E, ?>> filterator = new FilteringIterator<>(attributes.iterator(), basicFilter);
    if (filterator.hasNext()) {
        QueryBuilder qb = new QueryBuilder(context.getQueryBuilderOptions()).keyword(SELECT).commaSeparated(filterator, new QueryBuilder.Appender<Attribute<E, ?>>() {

            @Override
            public void append(QueryBuilder qb, Attribute<E, ?> value) {
                String versionColumn = context.getPlatform().versionColumnDefinition().columnName();
                if (value.isVersion() && versionColumn != null) {
                    qb.append(versionColumn).space().append(AS).space().append(value.getName()).space();
                } else {
                    qb.attribute(value);
                }
            }
        }).keyword(FROM).tableName(type.getName()).keyword(WHERE).appendWhereConditions(type.getKeyAttributes());
        String sql = qb.toString();
        try (Connection connection = context.getConnection();
            PreparedStatement statement = connection.prepareStatement(sql)) {
            int index = 1;
            for (Attribute<E, ?> attribute : type.getKeyAttributes()) {
                Object value = proxy.getKey(attribute);
                if (value == null) {
                    throw new MissingKeyException(proxy);
                }
                mapping.write((Expression) attribute, statement, index++, value);
            }
            context.getStatementListener().beforeExecuteQuery(statement, sql, null);
            ResultSet results = statement.executeQuery();
            context.getStatementListener().afterExecuteQuery(statement);
            if (results.next()) {
                Attribute[] selection = new Attribute[attributes.size()];
                attributes.toArray(selection);
                // modify the given entity
                if (type.isImmutable()) {
                    entity = fromBuilder(results, selection);
                } else {
                    entity = fromResult(entity, results, selection);
                }
            }
        } catch (SQLException e) {
            throw new PersistenceException(e);
        }
    }
    // refresh associations
    for (Attribute<E, ?> attribute : attributes) {
        // if it's a foreign key its resolved as part of the basic properties
        if (attribute.isAssociation()) {
            refreshAssociation(proxy, attribute);
        }
    }
    return entity;
}
Also used : QueryAttribute(io.requery.meta.QueryAttribute) Attribute(io.requery.meta.Attribute) WHERE(io.requery.sql.Keyword.WHERE) SQLException(java.sql.SQLException) FilteringIterator(io.requery.util.FilteringIterator) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) Predicate(io.requery.util.function.Predicate) ResultSet(java.sql.ResultSet) PersistenceException(io.requery.PersistenceException)

Aggregations

PersistenceException (io.requery.PersistenceException)8 SQLException (java.sql.SQLException)6 Connection (java.sql.Connection)4 Attribute (io.requery.meta.Attribute)2 QueryAttribute (io.requery.meta.QueryAttribute)2 PreparedStatement (java.sql.PreparedStatement)2 CollectionChanges (io.requery.proxy.CollectionChanges)1 UPDATE (io.requery.query.element.QueryType.UPDATE)1 WHERE (io.requery.sql.Keyword.WHERE)1 Platform (io.requery.sql.Platform)1 DefaultOutput (io.requery.sql.gen.DefaultOutput)1 FilteringIterator (io.requery.util.FilteringIterator)1 ObservableCollection (io.requery.util.ObservableCollection)1 Predicate (io.requery.util.function.Predicate)1 BatchUpdateException (java.sql.BatchUpdateException)1 DatabaseMetaData (java.sql.DatabaseMetaData)1 ResultSet (java.sql.ResultSet)1 Statement (java.sql.Statement)1 Timestamp (java.sql.Timestamp)1 ArrayList (java.util.ArrayList)1