Adding Drop Database operation to Spanner adapter

This commit is contained in:
Madhavan Sridharan 2024-10-03 16:52:17 -04:00
parent 1894f5f148
commit ccc15da0f0
10 changed files with 169 additions and 5 deletions

View File

@ -55,6 +55,8 @@ public class GCPSpannerOpMapper implements OpMapper<GCPSpannerBaseOp<?>> {
logger.info(() -> "Using '" + typeAndTarget.enumId + "' op type for op template '" + op.getName() + "'");
return switch (typeAndTarget.enumId) {
case drop_database_ddl ->
new GCPSpannerDropDatabaseDdlOpDispenser(adapter, op, typeAndTarget.targetFunction);
case create_database_ddl ->
new GCPSpannerCreateDatabaseDdlOpDispenser(adapter, op, typeAndTarget.targetFunction);
case update_database_ddl ->

View File

@ -26,8 +26,12 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.function.LongFunction;
/**
* Dispenser class for creating databases of {@link GCPSpannerCreateDatabaseDdlOp}.
*
* @see <a href="https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#createdatabaserequest">
* CreateDatabaseRequest</a> which can be a stretch goal to combine all of DB, Table(s), and Indexes into one-single call.
*/
public class GCPSpannerCreateDatabaseDdlOpDispenser extends GCPSpannerBaseOpDispenser {
private static final Logger logger = LogManager.getLogger(GCPSpannerCreateDatabaseDdlOpDispenser.class);

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2020-2024 nosqlbench
*
* 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.nosqlbench.adapter.gcpspanner.opdispensers;
import io.nosqlbench.adapter.gcpspanner.GCPSpannerDriverAdapter;
import io.nosqlbench.adapter.gcpspanner.ops.GCPSpannerBaseOp;
import io.nosqlbench.adapter.gcpspanner.ops.GCPSpannerDropDatabaseDdlOp;
import io.nosqlbench.adapters.api.templating.ParsedOp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.function.LongFunction;
/**
* Dispenser class for creating databases of {@link GCPSpannerDropDatabaseDdlOp}.
*
* @see <a href="https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#dropdatabaserequest">
* DropDatabaseRequest</a> which can be a stretch goal to combine all of DB, Table(s), and Indexes into one-single call.
*/
public class GCPSpannerDropDatabaseDdlOpDispenser extends GCPSpannerBaseOpDispenser {
private static final Logger logger = LogManager.getLogger(GCPSpannerDropDatabaseDdlOpDispenser.class);
private final LongFunction<GCPSpannerDropDatabaseDdlOp> opFunction;
/**
* Constructor for {@link GCPSpannerDropDatabaseDdlOpDispenser}.
*
* @param adapter the {@link GCPSpannerDriverAdapter} instance
* @param op the {@link ParsedOp} instance
* @param targetFunction a {@link LongFunction} that provides the target string
*/
public GCPSpannerDropDatabaseDdlOpDispenser(GCPSpannerDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
super(adapter, op, targetFunction);
this.opFunction = DropOpFunction(op);
}
/**
* Drops a {@link LongFunction} that generates {@link GCPSpannerDropDatabaseDdlOp} instances.
*
* @param op the {@link ParsedOp} instance
* @return a {@link LongFunction} that generates {@link GCPSpannerDropDatabaseDdlOp} instances
*/
private LongFunction<GCPSpannerDropDatabaseDdlOp> DropOpFunction(ParsedOp op) {
return (l) -> new GCPSpannerDropDatabaseDdlOp(
spaceFunction.apply(l).getSpanner(),
l,
targetFunction.apply(l),
spaceFunction.apply(l).getDbAdminClient(),
spaceFunction.apply(l).getDbAdminClient().getDatabase(spaceFunction.apply(l).getInstanceId(), spaceFunction.apply(l).getDatabaseIdString())
);
}
/**
* Retrieves an operation instance based on the provided value.
*
* @param value the long value used to generate the operation
* @return a {@link GCPSpannerBaseOp} instance
*/
@Override
public GCPSpannerBaseOp<?> getOp(long value) {
return opFunction.apply(value);
}
}

View File

@ -49,7 +49,7 @@ public class GCPSpannerCreateDatabaseDdlOp extends GCPSpannerBaseOp<Long> {
}
/**
* Applies the DDL update operation.
* Applies the DDL create operation.
*
* @param value the value to be used in the operation
* @return the result of the operation

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020-2024 nosqlbench
*
* 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.nosqlbench.adapter.gcpspanner.ops;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.Spanner;
/**
* This class represents an operation to Drop the database DDL (Data Definition Language) in Google Cloud Spanner.
* It extends the {@link GCPSpannerBaseOp} class and provides the implementation for applying the DDL update operation.
*/
public class GCPSpannerDropDatabaseDdlOp extends GCPSpannerBaseOp<Long> {
private final String databaseId;
private final DatabaseAdminClient dbAdminClient;
private final Database db;
/**
* Constructs a new {@link GCPSpannerUpdateDatabaseDdlOp}.
*
* @param searchIndexClient the {@link Spanner} client
* @param requestParam the request parameter
* @param databaseId the database ID to be dropped
* @param dbAdminClient the {@link DatabaseAdminClient} to execute the DDL update
* @param db the {@link Database} to be dropped
*/
public GCPSpannerDropDatabaseDdlOp(Spanner searchIndexClient, Long requestParam, String databaseId,
DatabaseAdminClient dbAdminClient, Database db) {
super(searchIndexClient, requestParam);
this.databaseId = databaseId;
this.dbAdminClient = dbAdminClient;
this.db = db;
}
/**
* Applies the DDL drop operation.
*
* @param value the value to be used in the operation
* @return the result of the operation
* @throws RuntimeException if an error occurs during the operation
*/
@Override
public Object applyOp(long value) {
try {
db.drop();
} catch (Exception e) {
logger.warn("Error dropping database using the Database object: {}. Will re-try using the DBAdminClient now...", e.getMessage());
try {
dbAdminClient.dropDatabase(databaseId, null);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
return null;
}
}

View File

@ -31,6 +31,7 @@ package io.nosqlbench.adapter.gcpspanner.types;
*/
public enum GCPSpannerOpType {
create_database_ddl,
drop_database_ddl,
update_database_ddl,
insert,
execute_dml,

View File

@ -1,10 +1,10 @@
scenarios:
default:
create_table_ddl: run driver=spanner tags==blocks:create_table_ddl service_account_file=TEMPLATE(service_account_file)
create_db_ddl: run driver=spanner tags==blocks:schema_db service_account_file=TEMPLATE(service_account_file)
project_id=TEMPLATE(project_id) instance_id=TEMPLATE(instance_id) database_id=TEMPLATE(database_id) cycles=1
blocks:
create_table_ddl:
schema_db:
ops:
op1:
create_database_ddl: |

View File

@ -0,0 +1,10 @@
scenarios:
default:
create_db_ddl: run driver=spanner tags==blocks:schema_drop_db service_account_file=TEMPLATE(service_account_file)
project_id=TEMPLATE(project_id) instance_id=TEMPLATE(instance_id) database_id=TEMPLATE(database_id) cycles=1
blocks:
schema_drop_db:
ops:
op1:
drop_database_ddl: "{database_id}"

View File

@ -9,5 +9,5 @@ blocks:
ops:
op1:
update_database_ddl: |
CREATE VECTOR INDEX VectorsIndex ON vectors(value)
CREATE VECTOR INDEX IF NOT EXISTS VectorsIndex ON vectors(value)
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);

View File

@ -8,4 +8,4 @@ blocks:
ops:
op1:
update_database_ddl: |
CREATE TABLE vectors (keycol STRING(100),value ARRAY<FLOAT32>(vector_length=>25) NOT NULL) PRIMARY KEY(keycol)
CREATE TABLE IF NOT EXISTS vectors (keycol STRING(100),value ARRAY<FLOAT32>(vector_length=>25) NOT NULL) PRIMARY KEY(keycol)