All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.oneandone.troilus.WriteQuery Maven / Gradle / Ivy

There is a newer version: 0.18
Show newest version
/*
 * Copyright 1&1 Internet AG, https://github.com/1and1/
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.oneandone.troilus;


import java.util.Set;

import net.oneandone.troilus.java7.Batchable;
import net.oneandone.troilus.java7.interceptor.CascadeOnWriteInterceptor;
import net.oneandone.troilus.java7.interceptor.WriteQueryData;
import net.oneandone.troilus.java7.interceptor.WriteQueryRequestInterceptor;

import com.datastax.driver.core.Statement;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;



/**
 * abstract write query implementation
 */
abstract class WriteQuery extends MutationQuery {
    
    private final WriteQueryData data;
  
    
    /**
     * @param ctx   the context
     * @param data  the data
     */
    WriteQuery(Context ctx, WriteQueryData data) {
        super(ctx);
        this.data = data;
    }
    
    protected WriteQueryData getData() {
        return data;
    }
    
    
    public CounterMutationQuery incr(String name) {
        return incr(name, 1);
    }
    
    public CounterMutationQuery incr(String name, long value) {
        return new CounterMutationQuery(getContext(), 
                                        new CounterMutationQueryData().keys(getData().getKeys())
                                                                      .whereConditions(getData().getWhereConditions())
                                                                      .name(name)
                                                                      .diff(value));  
    }
    
    public CounterMutationQuery decr(String name) {
        return decr(name, 1);
    }
    
    public CounterMutationQuery decr(String name, long value) {
        return new CounterMutationQuery(getContext(), 
                                        new CounterMutationQueryData().keys(getData().getKeys())
                                                                      .whereConditions(getData().getWhereConditions())
                                                                      .name(name)
                                                                      .diff(0 - value));  
    }
    
    protected ImmutableMap> addToMap(String name, Object key, Object value, ImmutableMap> values) {
        return (values == null) ? ImmutableMap.of(key, Optionals.toGuavaOptional(value)) : Immutables.join(values, key, Optionals.toGuavaOptional(value));
    }
    
    @Override
    public ListenableFuture executeAsync() {
        ListenableFuture future = super.executeAsync();
        
        Function validateLwtIfFunction = new Function() {
            @Override
            public Result apply(Result result) {
                if (isLwt() && !result.wasApplied()) {
                    throw new IfConditionException(result, "duplicated entry");
                }
                return result;
            }
        };
        return Futures.transform(future, validateLwtIfFunction);
    }

    
    
    private boolean isLwt() {
        return ((data.getIfNotExits() != null) && (data.getIfNotExits()) || !data.getOnlyIfConditions().isEmpty());                
    }
    

    
    public ListenableFuture getStatementAsync() {
        // perform request executors
        ListenableFuture queryDataFuture = executeRequestInterceptorsAsync(Futures.immediateFuture(data));        
        
        // query data to statement
        Function> queryDataToStatement = new Function>() {
            @Override
            public ListenableFuture apply(WriteQueryData queryData) {
                return WriteQueryDataImpl.toStatementAsync(queryData, getContext());
            }
        };
        
        
        ListenableFuture statementFuture = ListenableFutures.transform(queryDataFuture, queryDataToStatement, getContext().getTaskExecutor());
        if (getContext().getInterceptorRegistry().getInterceptors(CascadeOnWriteInterceptor.class).isEmpty()) {
            return statementFuture;
            
            
        // cascading statements   
        } else {
            ListenableFuture> cascadingStatmentsFuture = executeCascadeInterceptorsAsync(queryDataFuture);
            return mergeStatements(statementFuture, cascadingStatmentsFuture);
        }
    }
    
    
    
    
    private ListenableFuture executeRequestInterceptorsAsync(ListenableFuture queryDataFuture) {

        for (WriteQueryRequestInterceptor interceptor : getContext().getInterceptorRegistry().getInterceptors(WriteQueryRequestInterceptor.class).reverse()) {
            final WriteQueryRequestInterceptor icptor = interceptor;

            Function> mapperFunction = new Function>() {
                @Override
                public ListenableFuture apply(WriteQueryData queryData) {
                    return icptor.onWriteRequestAsync(queryData);
                }
            };

            // running interceptors within dedicated threads!
            queryDataFuture = ListenableFutures.transform(queryDataFuture, mapperFunction, getContext().getTaskExecutor());
        }

        return queryDataFuture; 
    }
    
    
    
    private ListenableFuture> executeCascadeInterceptorsAsync(ListenableFuture queryDataFuture) {
        Set>> statmentFutures = Sets.newHashSet();
        
        for (CascadeOnWriteInterceptor interceptor : getContext().getInterceptorRegistry().getInterceptors(CascadeOnWriteInterceptor.class).reverse()) {
            final CascadeOnWriteInterceptor icptor = interceptor;

            Function>>> querydataToBatchables = new Function>>>() {
                @Override
                public ListenableFuture>> apply(WriteQueryData queryData) {
                    return icptor.onWriteAsync(queryData);                    
                }
            };
            
            // running interceptors within dedicated threads!
            ListenableFuture>> batchablesFutureSet = ListenableFutures.transform(queryDataFuture, querydataToBatchables, getContext().getTaskExecutor());
            
            ListenableFuture> flattenStatementFutureSet = transformBatchablesToStatement(batchablesFutureSet);
            statmentFutures.add(flattenStatementFutureSet);
        }

        return ListenableFutures.flat(ImmutableSet.copyOf(statmentFutures), getContext().getTaskExecutor());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy