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

io.datarouter.gcp.spanner.op.read.index.write.SpannerBaseIndexDelete Maven / Gradle / Ivy

There is a newer version: 0.0.126
Show newest version
/*
 * Copyright © 2009 HotPads ([email protected])
 *
 * 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 io.datarouter.gcp.spanner.op.read.index.write;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;

import javax.annotation.Nullable;

import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.Key.Builder;
import com.google.cloud.spanner.KeySet;
import com.google.cloud.spanner.Mutation;
import com.google.cloud.spanner.Options;
import com.google.cloud.spanner.Options.ReadOption;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.TransactionContext;
import com.google.cloud.spanner.TransactionRunner.TransactionCallable;

import io.datarouter.gcp.spanner.field.SpannerBaseFieldCodec;
import io.datarouter.gcp.spanner.field.SpannerFieldCodecs;
import io.datarouter.gcp.spanner.op.SpannerBaseOp;
import io.datarouter.model.databean.Databean;
import io.datarouter.model.field.Field;
import io.datarouter.model.key.Key;
import io.datarouter.model.key.primary.PrimaryKey;
import io.datarouter.model.serialize.fielder.DatabeanFielder;
import io.datarouter.scanner.Scanner;
import io.datarouter.storage.config.Config;
import io.datarouter.storage.serialize.fieldcache.PhysicalDatabeanFieldInfo;

public abstract class SpannerBaseIndexDelete<
		PK extends PrimaryKey,
		D extends Databean,
		F extends DatabeanFielder,
		K extends Key>
extends SpannerBaseOp{

	protected final DatabaseClient client;
	protected final Config config;
	protected final SpannerFieldCodecs fieldCodecs;
	protected final String tableName;
	private final Collection keys;
	protected final PhysicalDatabeanFieldInfo fieldInfo;

	public SpannerBaseIndexDelete(
			DatabaseClient client,
			PhysicalDatabeanFieldInfo fieldInfo,
			Collection keys,
			Config config,
			SpannerFieldCodecs fieldCodecs){
		super("Spanner delete");
		this.keys = keys;
		this.fieldInfo = fieldInfo;
		this.client = client;
		this.config = config;
		this.fieldCodecs = fieldCodecs;
		this.tableName = fieldInfo.getTableName();
	}

	@Override
	public Void wrappedCall(){
		if(keys == null || keys.isEmpty()){
			return null;
		}
		String indexName = getIndexName(keys.iterator().next());

		TransactionCallable txn = new TransactionCallable<>(){
			@Nullable
			@Override
			public Void run(TransactionContext transactionContext){
				ReadOption[] readOptions = config.findLimit()
						.map(limit -> new ReadOption[]{Options.limit(limit)})
						.orElseGet(() -> new ReadOption[]{});
				try(ResultSet rs = transactionContext.readUsingIndex(
						tableName,
						indexName,
						buildKeySet(),
						fieldInfo.getPrimaryKeyFieldColumnNames(),
						readOptions)){
					List keyList = createFromResultSet(
							rs,
							fieldInfo.getPrimaryKeySupplier(),
							fieldInfo.getPrimaryKeyFields());
					Scanner.of(keyList)
							.map(key -> keyToDeleteMutation(key))
							.flush(transactionContext::buffer);
				}
				return null;
			}
		};

		client.readWriteTransaction().run(txn);

		return null;
	}

	public KeySet buildKeySet(){
		KeySet.Builder keySetBuilder = KeySet.newBuilder();
		keys.stream()
				.map(this::primaryKeyConversion)
				.forEach(keySetBuilder::addKey);
		return keySetBuilder.build();
	}

	protected abstract String getIndexName(K key);

	private com.google.cloud.spanner.Key primaryKeyConversion(K key){
		Builder mutationKey = com.google.cloud.spanner.Key.newBuilder();
		for(SpannerBaseFieldCodec codec : fieldCodecs.createCodecs(key.getFields())){
			mutationKey = codec.setKey(mutationKey);
		}
		return mutationKey.build();
	}

	protected Mutation keyToDeleteMutation(PK key){
		Builder mutationKey = com.google.cloud.spanner.Key.newBuilder();
		for(SpannerBaseFieldCodec codec : fieldCodecs.createCodecs(key.getFields())){
			mutationKey = codec.setKey(mutationKey);
		}
		return Mutation.delete(tableName, mutationKey.build());
	}

	protected List createFromResultSet(ResultSet set, Supplier emtpyObject, List> fields){
		List> codecs = fieldCodecs.createCodecs(fields);
		List objects = new ArrayList<>();
		while(set.next()){
			PK object = emtpyObject.get();
			codecs.forEach(codec -> codec.setField(object, set));
			objects.add(object);
		}
		return objects;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy