mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2024-11-30 12:34:01 -06:00
checkpoint on progress, naming indirection, primary key models, where predicates
This commit is contained in:
parent
3db4b88289
commit
a2077e8a98
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.converters.cql.exporters;
|
||||
|
||||
public record Binding(String name, String recipe) {
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.converters.cql.exporters;
|
||||
|
||||
import io.nosqlbench.converters.cql.cqlast.CqlColumnDef;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BindingsAccumulator {
|
||||
|
||||
private final NamingFolio namer;
|
||||
private final List<BindingsLibrary> libraries;
|
||||
private final Map<String,String> accumulated = new LinkedHashMap<>();
|
||||
|
||||
public BindingsAccumulator(NamingFolio namer, List<BindingsLibrary> libraries) {
|
||||
this.namer = namer;
|
||||
this.libraries = libraries;
|
||||
}
|
||||
|
||||
public Binding forColumn(CqlColumnDef def, String... extra) {
|
||||
String name = namer.nameFor(def, extra);
|
||||
for (BindingsLibrary library : libraries) {
|
||||
Optional<String> bindingRecipe = library.resolveBindingsFor(def);
|
||||
if (bindingRecipe.isPresent()) {
|
||||
Binding newBinding = new Binding(name, bindingRecipe.get());
|
||||
registerBinding(newBinding);
|
||||
return newBinding;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Unable to find a binding for column def '" + def + "'");
|
||||
}
|
||||
|
||||
private void registerBinding(Binding newBinding) {
|
||||
accumulated.put(newBinding.name(), newBinding.recipe());
|
||||
}
|
||||
|
||||
public Map<String,String> getAccumulatedBindings() {
|
||||
return accumulated;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.converters.cql.exporters;
|
||||
|
||||
import io.nosqlbench.converters.cql.cqlast.CqlColumnDef;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface BindingsLibrary {
|
||||
Optional<String> resolveBindingsFor(CqlColumnDef def);
|
||||
}
|
@ -47,30 +47,28 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class CqlWorkloadExporter {
|
||||
private final static Logger logger = LogManager.getLogger(CqlWorkloadExporter.class);
|
||||
public final static String DEFAULT_NAMING_TEMPLATE = "[OPTYPE-][COLUMN-][TYPEDEF][-TABLE!][-KEYSPACE]";
|
||||
public final static String DEFAULT_NAMING_TEMPLATE = "[OPTYPE-][COLUMN-][TYPEDEF-][TABLE!]-[KEYSPACE]";
|
||||
|
||||
private final Map<String, String> defaultBindings = new DefaultCqlBindings();
|
||||
private final BindingsLibrary defaultBindings = new DefaultCqlBindings();
|
||||
|
||||
private final NamingFolio namer;
|
||||
private final NamingFolio namer = new NamingFolio(DEFAULT_NAMING_TEMPLATE);
|
||||
private final BindingsAccumulator bindings = new BindingsAccumulator(namer, List.of(defaultBindings));
|
||||
private final CqlModel model;
|
||||
private final Map<String, String> bindingsMap = new LinkedHashMap<>();
|
||||
|
||||
public CqlWorkloadExporter(CqlModel model) {
|
||||
namer = new NamingFolio(DEFAULT_NAMING_TEMPLATE);
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public CqlWorkloadExporter(String ddl, Path srcpath) {
|
||||
namer = new NamingFolio(DEFAULT_NAMING_TEMPLATE);
|
||||
this.model = CqlModelParser.parse(ddl, srcpath);
|
||||
}
|
||||
|
||||
public CqlWorkloadExporter(String ddl) {
|
||||
namer = new NamingFolio(DEFAULT_NAMING_TEMPLATE);
|
||||
this.model = CqlModelParser.parse(ddl, null);
|
||||
}
|
||||
|
||||
public CqlWorkloadExporter(Path path) {
|
||||
namer = new NamingFolio(DEFAULT_NAMING_TEMPLATE);
|
||||
this.model = CqlModelParser.parse(path);
|
||||
}
|
||||
|
||||
@ -122,12 +120,13 @@ public class CqlWorkloadExporter {
|
||||
namer.populate(model);
|
||||
|
||||
Map<String, Object> workload = new LinkedHashMap<>();
|
||||
workload.put("bindings", defaultBindings);
|
||||
workload.put("bindings", bindingsMap);
|
||||
Map<String, Object> blocks = new LinkedHashMap<>();
|
||||
workload.put("blocks", blocks);
|
||||
blocks.put("schema", genSchemaBlock(model));
|
||||
blocks.put("rampup", genRampupBlock(model));
|
||||
blocks.put("main", genMainBlock(model));
|
||||
bindingsMap.putAll(bindings.getAccumulatedBindings());
|
||||
return workload;
|
||||
}
|
||||
|
||||
@ -137,7 +136,9 @@ public class CqlWorkloadExporter {
|
||||
mainOpTemplates.putAll(
|
||||
model.getAllTables()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(namer::nameFor, this::genUpsertTemplate))
|
||||
.collect(Collectors.toMap(
|
||||
t -> namer.nameFor(t, "optype", "insert"),
|
||||
this::genUpsertTemplate))
|
||||
);
|
||||
|
||||
mainOpTemplates.putAll(
|
||||
@ -201,19 +202,25 @@ public class CqlWorkloadExporter {
|
||||
logger.warn("Unknown literal format for " + typeName);
|
||||
}
|
||||
|
||||
return def.getName() + "=" + cqlLiteralFormat.format("{" + namer.nameFor(def) + "}");
|
||||
Binding binding = bindings.forColumn(def);
|
||||
|
||||
return def.getName() + "=" + cqlLiteralFormat.format("{" + binding.name() + "}");
|
||||
}
|
||||
|
||||
|
||||
private String genUpsertTemplate(CqlTable table) {
|
||||
List<CqlColumnDef> cdefs = table.getColumnDefinitions();
|
||||
return "insert into " + table.getKeySpace() + "." + table.getTableName() + "\n ( "
|
||||
+ cdefs.stream().map(cd -> cd.getName())
|
||||
return "insert into " +
|
||||
table.getKeySpace() + "." + table.getTableName() + "\n" +
|
||||
" ( " + cdefs.stream().map(CqlColumnDef::getName)
|
||||
.collect(Collectors.joining(" , ")) +
|
||||
" )\n values\n (" +
|
||||
cdefs
|
||||
.stream()
|
||||
.map(cd -> namer.nameFor(cd))
|
||||
.map(cd -> {
|
||||
Binding binding = bindings.forColumn(cd);
|
||||
return binding.name();
|
||||
})
|
||||
.collect(Collectors.joining("},{", "{", "}"))
|
||||
+ ");";
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ public class ElementNamer implements Function<Map<String, String>, String> {
|
||||
Pattern pattern = Pattern.compile("(?<prefix>[^\\]]+)?\\[(?<section>(?<pre>.*?)(?<name>[A-Z]+)(?<required>!)?(?<post>.*?))?]");
|
||||
Matcher scanner = pattern.matcher(template);
|
||||
while (scanner.find()) {
|
||||
if (scanner.group("prefix")!=null) {
|
||||
String prefix = scanner.group("prefix");
|
||||
sections.add(new Section(null, prefix, true));
|
||||
}
|
||||
if (scanner.group("section")!=null) {
|
||||
Section section = new Section(
|
||||
scanner.group("name").toLowerCase(),
|
||||
@ -56,10 +60,6 @@ public class ElementNamer implements Function<Map<String, String>, String> {
|
||||
scanner.group("required") != null);
|
||||
sections.add(section);
|
||||
}
|
||||
if (scanner.group("prefix")!=null) {
|
||||
String prefix = scanner.group("prefix");
|
||||
sections.add(new Section(null, prefix, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,13 @@ import io.nosqlbench.nb.api.labels.Labeled;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to put all the logic/complexity of name condensing into one place.
|
||||
* Basically if you have identifiers that are globally unique within the active namespace,
|
||||
* <EM>WITHOUT</EM> using fully qualified names, then it is easier for users to use short names.
|
||||
* For example, if you have a column named "score" which is used as an int in one table and as
|
||||
* a double in another, then you must include the type information to provide two distinct identifiers
|
||||
* for the purpose of mapping bindings.
|
||||
*
|
||||
* This will be a pre-built inverted index of all field which need to have bindings assigned.
|
||||
* A field reference is presumed to be unique within the scope from which the traversal to
|
||||
* the working set has a single path.
|
||||
|
Loading…
Reference in New Issue
Block a user