Search in sources :

Example 1 with Tuple

use of com.mysema.query.Tuple in project opencast by opencast.

the class AbstractADeleteQuery method run.

public long run(DeleteSnapshotHandler deleteSnapshotHandler) {
    // run query and map the result to records
    final long startTime = System.nanoTime();
    // resolve AST
    final DeleteQueryContribution c = contributeDelete(owner);
    // run all queries in a single transaction
    final DeletionResult deletion = am.getDb().run(new Fn<JPAQueryFactory, DeletionResult>() {

        @Override
        public DeletionResult apply(final JPAQueryFactory jpa) {
            return runQueries(jpa, c);
        }
    });
    logger.debug("Pure query ms " + (System.nanoTime() - startTime) / 1000000);
    // delete from store
    for (Tuple t : deletion.deletedSnapshots) {
        // all three t.get(..) calls won't return null since the database fields are not null.
        final String orgId = t.get(Q_SNAPSHOT.organizationId);
        final String mpId = t.get(Q_SNAPSHOT.mediaPackageId);
        final VersionImpl version = Conversions.toVersion(t.get(Q_SNAPSHOT.version));
        am.getAssetStore().delete(DeletionSelector.delete(orgId, mpId, version));
        deleteSnapshotHandler.notifyDeleteSnapshot(mpId, version);
    }
    for (String mpId : deletion.deletedEpisodes) {
        deleteSnapshotHandler.notifyDeleteEpisode(mpId);
    }
    final long searchTime = (System.nanoTime() - startTime) / 1000000;
    logger.debug("Complete query ms " + searchTime);
    return deletion.deletedItemsCount;
}
Also used : JPAQueryFactory(com.mysema.query.jpa.impl.JPAQueryFactory) Tuple(com.mysema.query.Tuple) VersionImpl(org.opencastproject.assetmanager.impl.VersionImpl)

Example 2 with Tuple

use of com.mysema.query.Tuple in project opencast by opencast.

the class AbstractASelectQuery method toARecord.

/**
 * Transform a Querydsl result {@link Tuple} into an {@link ARecord}.
 * To do the transformation I need to know what targets have been selected.
 */
private Fn<Tuple, ARecordImpl> toARecord(final SelectQueryContribution c) {
    return new Fn<Tuple, ARecordImpl>() {

        @Override
        public ARecordImpl apply(Tuple tuple) {
            final String mediaPackageId;
            SnapshotDto snapshotDto = null;
            final long id;
            // Only fetch the snapshot if it is in the fetch list.
            if (c.fetch.exists(Booleans.<Expression<?>>eq(Q_SNAPSHOT))) {
                snapshotDto = RequireUtil.notNull(tuple.get(Q_SNAPSHOT), "[BUG] snapshot table data");
                id = snapshotDto.getId();
                mediaPackageId = snapshotDto.getMediaPackageId();
            } else {
                // The media package ID and the snapshot's database ID must always be fetched.
                id = RequireUtil.notNull(tuple.get(Q_SNAPSHOT.id), "[BUG] snapshot table id");
                mediaPackageId = RequireUtil.notNull(tuple.get(Q_SNAPSHOT.mediaPackageId), "[BUG] snapshot table media package id");
            }
            return new ARecordImpl(id, mediaPackageId, Stream.<Property>empty(), snapshotDto);
        }
    };
}
Also used : SnapshotDto(org.opencastproject.assetmanager.impl.persistence.SnapshotDto) Fn(com.entwinemedia.fn.Fn) Tuple(com.mysema.query.Tuple)

Example 3 with Tuple

use of com.mysema.query.Tuple in project opencast by opencast.

the class AbstractADeleteQuery method runQueries.

/**
 * Run this in a transaction.
 */
private DeletionResult runQueries(JPAQueryFactory jpa, DeleteQueryContribution c) {
    // # create Querydsl delete clause
    // # from
    // put into a set to remove duplicates
    final EntityPath<?> from;
    {
        final Set<EntityPath<?>> f = c.from.toSet(SetB.MH);
        if (f.size() == 1) {
            from = $(f).head2();
        } else {
            throw new RuntimeException("Only one entity is allowed in the from clause");
        }
    }
    // 
    if (from instanceof QSnapshotDto) {
        // from Snapshot
        // 
        final BooleanExpression where = Expressions.allOf(c.targetPredicate.orNull(), c.where.apply(Q_SNAPSHOT));
        // get snapshots to delete
        // TODO ATTENTION: this query has the potential to yield a massive amount of elements
        // return the list of snapshots to delete them outside the transaction since
        // it may take a while.
        final List<Tuple> deletedSnapshots = jpa.query().from(Q_SNAPSHOT).where(where).list(Q_SNAPSHOT.organizationId, Q_SNAPSHOT.mediaPackageId, Q_SNAPSHOT.version);
        // <BLOCK>
        // TODO database only approach to determine deleted episodes
        // TODO does not run with H2 so unit tests break
        /*
SELECT
  e.mediapackage_id,
  count(*) AS v
FROM oc_assets_snapshot e
GROUP BY e.mediapackage_id
HAVING v = (SELECT count(*)
            FROM oc_assets_snapshot e2
            WHERE e.mediapackage_id = e2.mediapackage_id
                  AND
                  -- delete where clause
                  (e2.version = 2 OR e2.mediapackage_id = '24ec925e-ea57-43a5-a7bb-58dc5aae54dd')
            GROUP BY mediapackage_id);
       */
        // final QSnapshotDto e2 = new QSnapshotDto("eee");
        // final List<String> deletedSnapshots = jpa.query()
        // .from(e2)
        // .groupBy(e2.mediaPackageId)
        // .having(e2.count().eq(
        // jpa.subQuery()
        // .from(Q_SNAPSHOT)
        // .where(Q_SNAPSHOT.mediaPackageId.eq(e2.mediaPackageId).and(where))
        // .groupBy(Q_SNAPSHOT.mediaPackageId)
        // .count()))
        // .list(e2.mediaPackageId);
        // </BLOCK>
        // delete assets from database
        final JPADeleteClause qAssets = jpa.delete(Q_ASSET).where(Q_ASSET.snapshotId.in(new JPASubQuery().from(Q_SNAPSHOT).where(where).list(Q_SNAPSHOT.id)));
        am.getDb().logDelete(formatQueryName(c.name, "delete assets"), qAssets);
        qAssets.execute();
        // main delete query
        final JPADeleteClause qMain = jpa.delete(Q_SNAPSHOT).where(where);
        am.getDb().logDelete(formatQueryName(c.name, "main"), qMain);
        final long deletedItems = qMain.execute();
        // delete orphaned properties
        deleteOrphanedProperties();
        // <BLOCK>
        // TODO Bad solution. Yields all media package IDs which can easily be thousands
        // TODO The above SQL solution does not work with H2 so I suspect the query is not 100% clean
        // TODO Rework the query and replace this code.
        // calculate deleted episodes, i.e. where all snapshots have been deleted
        final Set<String> deletedEpisodes;
        {
            final List<String> remainingSnapshots = jpa.query().from(Q_SNAPSHOT).distinct().list(Q_SNAPSHOT.mediaPackageId);
            final Set<String> d = $(deletedSnapshots).map(new Fn<Tuple, String>() {

                @Override
                public String apply(Tuple tuple) {
                    return tuple.get(Q_SNAPSHOT.mediaPackageId);
                }
            }).toSet(SetB.MH);
            d.removeAll(remainingSnapshots);
            deletedEpisodes = Collections.unmodifiableSet(d);
        }
        // </BLOCK>
        return new DeletionResult(deletedItems, deletedSnapshots, deletedEpisodes);
    } else if (from instanceof QPropertyDto) {
        // from Property
        // 
        final BooleanExpression where;
        {
            final BooleanExpression w = c.where.apply(Q_PROPERTY);
            if (w != null) {
                /* The original sub query used an "ON" clause to filter the join by mediapackage id [1].
             Unfortunately Eclipse link drops this clause completely when transforming the query
             into SQL. It creates a cross join instead of the inner join, which is perfectly legal
             if the "ON" clause would be moved to the "WHERE" clause.
             The example [2] shows that neither an "ON" clause nor an additional "WHERE" predicate is generated.

             [1]
             new JPASubQuery()
                .from(Q_PROPERTY)
                .join(Q_SNAPSHOT) <- inner join
                .on(Q_PROPERTY.mediaPackageId.eq(Q_SNAPSHOT.mediaPackageId)) <- dropped by Eclipse link
                .where(Q_PROPERTY.mediaPackageId.eq(Q_SNAPSHOT.mediaPackageId).and(w))
                .distinct()
                .list(Q_PROPERTY.mediaPackageId)

             [2]
             SELECT DISTINCT t1.mediapackage_id FROM oc_assets_snapshot t2, oc_assets_properties t1 WHERE (t2.organization_id = ?)
           */
                where = Q_PROPERTY.mediaPackageId.in(new JPASubQuery().from(Q_PROPERTY).join(Q_SNAPSHOT).where(Q_PROPERTY.mediaPackageId.eq(Q_SNAPSHOT.mediaPackageId).and(w)).distinct().list(Q_PROPERTY.mediaPackageId));
            } else {
                where = null;
            }
        }
        final JPADeleteClause qProperties = jpa.delete(from).where(Expressions.allOf(c.targetPredicate.orNull(), where));
        am.getDb().logDelete(formatQueryName(c.name, "main"), qProperties);
        final long deletedItems = qProperties.execute();
        return new DeletionResult(deletedItems, Collections.<Tuple>emptyList(), Collections.<String>emptySet());
    } else {
        // from contains an unsupported entity
        throw new RuntimeException("[Bug]");
    }
}
Also used : Set(java.util.Set) JPADeleteClause(com.mysema.query.jpa.impl.JPADeleteClause) QPropertyDto(org.opencastproject.assetmanager.impl.persistence.QPropertyDto) BooleanExpression(com.mysema.query.types.expr.BooleanExpression) JPASubQuery(com.mysema.query.jpa.JPASubQuery) QSnapshotDto(org.opencastproject.assetmanager.impl.persistence.QSnapshotDto) List(java.util.List) Tuple(com.mysema.query.Tuple)

Aggregations

Tuple (com.mysema.query.Tuple)3 Fn (com.entwinemedia.fn.Fn)1 JPASubQuery (com.mysema.query.jpa.JPASubQuery)1 JPADeleteClause (com.mysema.query.jpa.impl.JPADeleteClause)1 JPAQueryFactory (com.mysema.query.jpa.impl.JPAQueryFactory)1 BooleanExpression (com.mysema.query.types.expr.BooleanExpression)1 List (java.util.List)1 Set (java.util.Set)1 VersionImpl (org.opencastproject.assetmanager.impl.VersionImpl)1 QPropertyDto (org.opencastproject.assetmanager.impl.persistence.QPropertyDto)1 QSnapshotDto (org.opencastproject.assetmanager.impl.persistence.QSnapshotDto)1 SnapshotDto (org.opencastproject.assetmanager.impl.persistence.SnapshotDto)1