<commit_before>package org.commcare.cases.model;

import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.instance.TreeElement;
import org.javarosa.core.services.storage.IMetaData;
import org.javarosa.core.services.storage.Persistable;
import org.javarosa.core.util.externalizable.DeserializationException;
import org.javarosa.core.util.externalizable.ExtUtil;
import org.javarosa.core.util.externalizable.ExtWrapList;
import org.javarosa.core.util.externalizable.PrototypeFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.Vector;

/**
 * A DB model for storing TreeElements such that particular attributes and
 * elements are indexed and queryable using the DB.
 *
 * Indexed attributes/elements get their own table columns, and the rest of
 * the TreeElement is stored as a serialized blob.
 *
 * @author <NAME> (<EMAIL>)
 */
public class StorageIndexedTreeElementModel implements Persistable, IMetaData {

    private static final String STORAGE_KEY_PREFIX = "IND_FIX_";
    private static final String DASH_ESCAPE = "\\$\\$";
    private static final String ATTR_PREFIX = "_$";
    private static final String ELEM_PREFIX = "_0";

    private String[] metaDataFields = null;
    private Vector<String> indices;
    private TreeElement root;

    protected int recordId = -1;
    protected String entityId;

    @SuppressWarnings("unused")
    public StorageIndexedTreeElementModel() {
        // for serialization
    }

    public StorageIndexedTreeElementModel(Set<String> indices, TreeElement root) {
        this.indices = new Vector<>(indices);
        this.root = root;
        metaDataFields = buildMetadataFields(this.indices);
    }

    private static String[] buildMetadataFields(List<String> indices) {
        String[] escapedIndexList = new String[indices.size()];
        int i = 0;
        for (String index : indices) {
            escapedIndexList[i++] = getColFromEntry(index);
        }
        return escapedIndexList;
    }

    public static String getTableName(String fixtureName) {
        String cleanedName = fixtureName.replace(":", "_").replace(".", "_").replace("-", "_");
        return STORAGE_KEY_PREFIX + cleanedName;
    }

    @Override
    public String[] getMetaDataFields() {
        return metaDataFields;
    }

    @Override
    public Object getMetaData(String fieldName) {
        if (fieldName.startsWith(ATTR_PREFIX)) {
            return root.getAttributeValue(null, getEntryFromCol(fieldName).substring(1));
        } else if (fieldName.startsWith(ELEM_PREFIX)) {
            // NOTE PLM: The usage of getChild of '0' below assumes indexes
            // are only made over entries with multiplicity 0
            TreeElement child = root.getChild(getEntryFromCol(fieldName), 0);
            IAnswerData value = child.getValue();
            if (value == null) {
                return "";
            } else {
                return value.uncast().getString();
            }
        }
        return null;
    }

    @Override
    public void setID(int id) {
        this.recordId = id;
    }

    @Override
    public int getID() {
        return recordId;
    }<commit_msg>Throw exception on bad field name<commit_after>package org.commcare.cases.model;

import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.instance.TreeElement;
import org.javarosa.core.services.storage.IMetaData;
import org.javarosa.core.services.storage.Persistable;
import org.javarosa.core.util.externalizable.DeserializationException;
import org.javarosa.core.util.externalizable.ExtUtil;
import org.javarosa.core.util.externalizable.ExtWrapList;
import org.javarosa.core.util.externalizable.PrototypeFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.Vector;

/**
 * A DB model for storing TreeElements such that particular attributes and
 * elements are indexed and queryable using the DB.
 *
 * Indexed attributes/elements get their own table columns, and the rest of
 * the TreeElement is stored as a serialized blob.
 *
 * @author <NAME> (<EMAIL>)
 */
public class StorageIndexedTreeElementModel implements Persistable, IMetaData {

    private static final String STORAGE_KEY_PREFIX = "IND_FIX_";
    private static final String DASH_ESCAPE = "\\$\\$";
    private static final String ATTR_PREFIX = "_$";
    private static final String ELEM_PREFIX = "_0";

    private String[] metaDataFields = null;
    private Vector<String> indices;
    private TreeElement root;

    protected int recordId = -1;
    protected String entityId;

    @SuppressWarnings("unused")
    public StorageIndexedTreeElementModel() {
        // for serialization
    }

    public StorageIndexedTreeElementModel(Set<String> indices, TreeElement root) {
        this.indices = new Vector<>(indices);
        this.root = root;
        metaDataFields = buildMetadataFields(this.indices);
    }

    private static String[] buildMetadataFields(List<String> indices) {
        String[] escapedIndexList = new String[indices.size()];
        int i = 0;
        for (String index : indices) {
            escapedIndexList[i++] = getColFromEntry(index);
        }
        return escapedIndexList;
    }

    public static String getTableName(String fixtureName) {
        String cleanedName = fixtureName.replace(":", "_").replace(".", "_").replace("-", "_");
        return STORAGE_KEY_PREFIX + cleanedName;
    }

    @Override
    public String[] getMetaDataFields() {
        return metaDataFields;
    }

    @Override
    public Object getMetaData(String fieldName) {
        if (fieldName.startsWith(ATTR_PREFIX)) {
            return root.getAttributeValue(null, getEntryFromCol(fieldName).substring(1));
        } else if (fieldName.startsWith(ELEM_PREFIX)) {
            // NOTE PLM: The usage of getChild of '0' below assumes indexes
            // are only made over entries with multiplicity 0
            TreeElement child = root.getChild(getEntryFromCol(fieldName), 0);
            IAnswerData value = child.getValue();
            if (value == null) {
                return "";
            } else {
                return value.uncast().getString();
            }
        }
        throw new IllegalArgumentException("No metadata field " + fieldName + " in the indexed fixture storage table.");
    }

    @Override
    public void setID(int id) {
        this.recordId = id;
    }

    @Override
    public int getID() {
        return recordId;
    }
{'fraction_non_alphanumeric': 0.09873760144274121, 'fraction_numerical': 0.0021039975954313195, 'mean_word_length': 3.0604026845637584, 'pattern_counts': {'":': 2, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6442254', 'n_tokens_mistral': 1845, 'n_tokens_neox': 1818, 'n_words': 481}