private static void buildColumnDecls( List<DataType> dataTypes, List<List<AttributeValue>> universe, Map<String, ColumnDecl> built) { for (DataType dt : dataTypes) { if (universe == null) { ColumnDecl cd = buildDecl(dt, null); built.put(cd.getDecl(), cd); } else { for (List<AttributeValue> combo : universe) { ColumnDecl cd = buildDecl(dt, combo); built.put(cd.getDecl(), cd); } } } }
private static List<String> buildTableDecls( List<DataType> dataTypes, List<ColumnAttribute> attrTypes) { LinkedHashMap<String, ColumnDecl> uniqueDecls = new LinkedHashMap<String, ColumnDecl>(); TreeMap<String, ColumnDecl> regularDecls = new TreeMap<String, ColumnDecl>(); // unique decls are those that are declared autoincrement or primary key // there is one of each where appropriate; these all go in the uniqueDecls set. // regular decls involve every combo of non pk/autoinc attributes. if there are multiple // variants // then we do one of each variant. ColumnAttribute pk = null; ColumnAttribute ai = null; List<ColumnAttribute> variables = new ArrayList<ColumnAttribute>(); for (Iterator<ColumnAttribute> iter = attrTypes.iterator(); iter.hasNext(); ) { ColumnAttribute ca = iter.next(); if (ca.getType() == AttributeType.AUTOINCREMENT) { ai = ca; iter.remove(); } else if (ca.getType() == AttributeType.PRIMARY) { pk = ca; iter.remove(); } else if (ca.getVariants() > 1) variables.add(ca); } List<List<AttributeValue>> nakedUniverse = new ArrayList<List<AttributeValue>>(); List<List<AttributeValue>> pkUniverse = new ArrayList<List<AttributeValue>>(); List<List<AttributeValue>> aiUniverse = new ArrayList<List<AttributeValue>>(); for (ColumnAttribute ca : variables) { for (int i = 0; i < ca.getVariants(); i++) { List<AttributeValue> combo = new ArrayList<AttributeValue>(); for (ColumnAttribute ica : attrTypes) { if (ica == ca) { combo.add(new AttributeValue(ica, i)); } else { combo.add(new AttributeValue(ica, 0)); } } nakedUniverse.add(combo); List<AttributeValue> pkPrefix = new ArrayList<AttributeValue>(); pkPrefix.add(new AttributeValue(pk, 0)); pkPrefix.addAll(combo); pkUniverse.add(pkPrefix); List<AttributeValue> aiPrefix = new ArrayList<AttributeValue>(); aiPrefix.add(new AttributeValue(ai, 0)); aiPrefix.addAll(combo); aiUniverse.add(aiPrefix); } } Set<Set<ColumnAttribute>> ps = Sets.powerSet(new LinkedHashSet<ColumnAttribute>(attrTypes)); List<List<AttributeValue>> vps = new ArrayList<List<AttributeValue>>(); for (Set<ColumnAttribute> s : ps) { // also off of the powerset arrange for variants List<AttributeValue> entry = new ArrayList<AttributeValue>(); List<ColumnAttribute> variants = new ArrayList<ColumnAttribute>(); for (ColumnAttribute ca : s) { entry.add(new AttributeValue(ca, 0)); if (ca.getVariants() > 1) { variants.add(ca); } } vps.add(entry); for (ColumnAttribute oca : variants) { for (int i = 1; i < oca.getVariants(); i++) { List<AttributeValue> ventry = new ArrayList<AttributeValue>(); for (ColumnAttribute ica : s) { if (ica == oca) { ventry.add(new AttributeValue(ica, i)); } else { ventry.add(new AttributeValue(ica, 0)); } } vps.add(ventry); } } } System.out.println("|nakedUniverse|=" + nakedUniverse.size()); System.out.println("|pkUniverse|=" + pkUniverse.size()); System.out.println("|aiUniverse|=" + aiUniverse.size()); System.out.println("|vps|=" + vps.size()); List<List<AttributeValue>> pkOnly = buildSingleList(pk); List<DataType> nonTextTypes = Functional.select( dataTypes, new UnaryPredicate<DataType>() { @Override public boolean test(DataType object) { return !(object.isTextType() || object.isBlobType()); } }); // pk decls with a ton of attributes; note that we don't generate for text types // due to the key length thing, will have to come back to this buildColumnDecls(nonTextTypes, pkUniverse, uniqueDecls); // ai decls with a ton of attributes buildColumnDecls(nonTextTypes, aiUniverse, uniqueDecls); // pk only decls buildColumnDecls(nonTextTypes, pkOnly, uniqueDecls); // no attributes buildColumnDecls(dataTypes, null, regularDecls); // all combos of attributes buildColumnDecls(dataTypes, vps, regularDecls); System.out.println("|uniqueDecls|=" + uniqueDecls.size()); System.out.println("|regularDecls|=" + regularDecls.size()); int nreg = (regularDecls.size() / uniqueDecls.size()) + 1; List<String> out = new ArrayList<String>(uniqueDecls.size()); int tcounter = 0; for (ColumnDecl cd : uniqueDecls.values()) { StringBuilder buf = new StringBuilder(); buf.append("create table `t") .append(++tcounter) .append("` (") .append(PEConstants.LINE_SEPARATOR); buf.append("`c0` ").append(cd.getDecl()); for (int i = 0; i < nreg; i++) { if (!regularDecls.isEmpty()) { buf.append(",").append(PEConstants.LINE_SEPARATOR); ColumnDecl icd = regularDecls.firstEntry().getValue(); regularDecls.remove(icd.getDecl()); buf.append("`c").append(i + 1).append("` ").append(icd.getDecl()); } } buf.append(")"); out.add(buf.toString()); } return out; }