@Override public Long insert(final Subscription subscription) { Long result = dbi.withHandle( new HandleCallback<Long>() { @Override public Long withHandle(Handle handle) throws Exception { return handle .createStatement( "insert into subscriptions (topic, metadata, channel) values (:topic, :metadata, :channel)") .bind("topic", subscription.getTopic()) .bind("metadata", mapper.writeValueAsString(subscription.getMetadata())) .bind("channel", subscription.getChannel()) .executeAndReturnGeneratedKeys(LongMapper.FIRST) .first(); } }); if (!Strings.isNullOrEmpty(subscription.getMetadata().getFeed())) { subscriptionCache.removeFeedSubscriptions(subscription.getMetadata().getFeed()); } if (!Strings.isNullOrEmpty(subscription.getTopic())) { subscriptionCache.removeTopicSubscriptions(subscription.getTopic()); } return result; }
public Set<Subscription> loadByFeed(final String feed) { Set<Subscription> subscriptions = subscriptionCache.loadFeedSubscriptions(feed); if (subscriptions != null && !subscriptions.isEmpty()) { return subscriptions; } return dbi.withHandle( new HandleCallback<Set<Subscription>>() { @Override public Set<Subscription> withHandle(Handle handle) throws Exception { FeedEventMetaData metadata = new FeedEventMetaData(feed); Set<Subscription> subscriptions = ImmutableSet.copyOf( handle .createQuery( "select id, metadata, channel, topic from subscriptions where metadata = :metadata") .bind("metadata", mapper.writeValueAsString(metadata)) .map(new SubscriptionMapper()) .list()); subscriptionCache.addFeedSubscriptions(feed, subscriptions); return subscriptions; } }); }
@Override public Set<Subscription> loadByTopic(final String topicQuery) { final Set<String> topicSubQueries = decomposeTopicQuery(topicQuery); final Map<String, Optional<Subscription>> cachedResults = subscriptionCache.loadTopicSubscriptions(topicSubQueries); final Set<Subscription> result = new HashSet<Subscription>(); // Iterate through the results from the cache, and remove any topics // that were found from the list of topics left to query, and add // the non-null subscriptions to the list of results for (String topic : cachedResults.keySet()) { if (cachedResults.get(topic).isPresent()) { result.add(cachedResults.get(topic).get()); topicSubQueries.remove(topic); } } // all topics that are found in the cache will be removed, so if no // topic subqueries are left, we are done if (!topicSubQueries.isEmpty()) { Collection<Subscription> dbResults = dbi.withHandle( new HandleCallback<Collection<Subscription>>() { @Override public Collection<Subscription> withHandle(Handle handle) throws Exception { final Set<Subscription> dbResult = new HashSet<Subscription>(); InClauseExpander in = new InClauseExpander(topicSubQueries); Iterator<Subscription> subscriptionsIter = handle .createQuery( "select id, metadata, channel, topic from subscriptions where topic in (" + in.getExpansion() + ")") .bindNamedArgumentFinder(in) .map(new SubscriptionMapper()) .iterator(); if (subscriptionsIter != null) { while (subscriptionsIter.hasNext()) { Subscription dbSubscription = subscriptionsIter.next(); dbResult.add(dbSubscription); subscriptionCache.addTopicSubscriptions( dbSubscription.getTopic(), Optional.of(dbSubscription)); topicSubQueries.remove(dbSubscription.getTopic()); } } return dbResult; } }); // Add the database results to the results from the cache result.addAll(dbResults); // Add empty subscriptions to the cache if (!topicSubQueries.isEmpty()) { subscriptionCache.addEmptyTopicSubscriptions(topicSubQueries); } } return ImmutableSet.copyOf(result); }
@Override public void cleanUp() { subscriptionCache.cleanUp(); }