<commit_before>package org.openforis.collect.persistence;

import static org.openforis.collect.persistence.jooq.Sequences.DATA_ID_SEQ;
import static org.openforis.collect.persistence.jooq.tables.Data.DATA;

import java.util.HashMap;

import org.jooq.BatchBindStep;
import org.jooq.InsertValuesStep;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.impl.Factory;
import org.openforis.collect.model.CollectRecord;
import org.openforis.collect.persistence.jooq.JooqDaoSupport;
import org.openforis.collect.persistence.jooq.tables.records.DataRecord;
import org.openforis.idm.metamodel.NodeDefinition;
import org.openforis.idm.metamodel.Schema;
import org.openforis.idm.metamodel.Survey;
import org.openforis.idm.model.Attribute;
import org.openforis.idm.model.Entity;
import org.openforis.idm.model.Field;
import org.openforis.idm.model.Node;
import org.openforis.idm.model.NodeVisitor;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author <NAME>
 */
public class DataDao extends JooqDaoSupport {

	@Transactional
	public void insertData(CollectRecord record) {
		// N.B.: traversal order matters; dfs so that parent id's are assigned before children
		Entity root = record.getRootEntity();
		InsertQueryNodeVisitor visitor = new InsertQueryNodeVisitor();
		root.traverse(visitor);
		BatchBindStep batch = visitor.getBatch();
		batch.execute();
	}

	private class InsertQueryNodeVisitor implements NodeVisitor {
		private BatchBindStep batch;
		
		public InsertQueryNodeVisitor() {
			Factory jf = getJooqFactory();
			InsertValuesStep<DataRecord> query = jf.insertInto(
					DATA, 
					DATA.ID,
					DATA.DEFINITION_ID, 
					DATA.RECORD_ID, 
					DATA.POSITION, 
					DATA.PARENT_ID,
					DATA.FIELD,
					DATA.VALUE,
					DATA.REMARKS,
					DATA.SYMBOL
				)
				//.values("?", "?", "?", "?", "?", "?", "?", "?", "?");
				.values(null, null, null, null, null, null, null, null, null);
			batch = jf.batch(query);
		}
		
		@Override
		public void visit(Node<? extends NodeDefinition> node, int idx) {
			insert(node, idx);
		}
		
		public BatchBindStep getBatch() {
			return batch;
		}
		
		private void insert(Node<?> node, int idx) {
			CollectRecord record = (CollectRecord) node.getRecord();
			Integer recordId = record.getId();
			Integer parentId = getParentId(node);
			NodeDefinition defn = node.getDefinition();
			Integer defnId = defn.getId();
			if ( defnId == null ) {
				throw new NullPointerException("Null schema object definition id");			
			}
			Integer id;
			if ( node instanceof Entity ) {
				id = addRecord(defnId, recordId, idx + 1, parentId, 1, null, null, null);
				node.setId(id);
			} else if ( node instanceof Attribute ) {
				addAttribute(defnId, recordId, idx + 1, parentId, (Attribute<?,?>) node);
			} else {
				throw new RuntimeException("Unknown node "+node.getClass());
			}
		}

		private void addAttribute(Integer defnId, Integer recordId, Integer position, Integer parentId, Attribute<?, ?> attribute) {
			for (int f = 0; f < attribute.getFieldCount(); f++) {
				Field<?> field = attribute.getField(f);
				Object value = field.getValue();
				String valueString = value == null ? null : value.toString();
				Character symbol = field.getSymbol();
				String symbolString = symbol == null ? null : symbol.toString();
				addRecord(defnId, recordId, position, parentId, f+1, valueString, field.getRemarks(), symbolString);
			}
		}
		
		private Integer addRecord(Integer defnId, Integer recordId, Integer idx, Integer parentId, Integer field, String value, String remarks, String symbol) {
			Factory jf = getJooqFactory();
			Integer id = jf.nextval(DATA_ID_SEQ).intValue();
			batch.bind(id, defnId, recordId, idx, parentId, field, value, remarks, symbol);
			/*
			query.addValue(DATA.ID, id);
			query.addValue(DATA.DEFINITION_ID, defnId);
			query.addValue(DATA.RECORD_ID, recordId);
			query.addValue(DATA.POSITION, idx);
			query.addValue(DATA.PARENT_ID, parentId);
			query.addValue(DATA.FIELD, field);
			query.addValue(DATA.VALUE, value);
			query.addValue(DATA.REMARKS, remarks);
			query.addValue(DATA.SYMBOL, symbol);
			query.newRecord();
			*/
			return id;
		}
		
		private Integer getParentId(Node<?> node) {
			Integer parentId = null;
			Entity parent = node.getParent();
			if ( parent != null ) {
				parentId = parent.getId();
				if ( parentId == null ) {
					throw new IllegalStateException("Unsaved parent");
				}
			}
			return parentId;
		}
	}
	

	void load(CollectRecord record) throws DataInconsistencyException {
		// Fetch all data for one record<commit_msg>Code clean<commit_after>package org.openforis.collect.persistence;

import static org.openforis.collect.persistence.jooq.Sequences.DATA_ID_SEQ;
import static org.openforis.collect.persistence.jooq.tables.Data.DATA;

import java.util.HashMap;

import org.jooq.BatchBindStep;
import org.jooq.InsertValuesStep;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.impl.Factory;
import org.openforis.collect.model.CollectRecord;
import org.openforis.collect.persistence.jooq.JooqDaoSupport;
import org.openforis.collect.persistence.jooq.tables.records.DataRecord;
import org.openforis.idm.metamodel.NodeDefinition;
import org.openforis.idm.metamodel.Schema;
import org.openforis.idm.metamodel.Survey;
import org.openforis.idm.model.Attribute;
import org.openforis.idm.model.Entity;
import org.openforis.idm.model.Field;
import org.openforis.idm.model.Node;
import org.openforis.idm.model.NodeVisitor;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author <NAME>
 */
public class DataDao extends JooqDaoSupport {

	@Transactional
	public void insertData(CollectRecord record) {
		// N.B.: traversal order matters; dfs so that parent id's are assigned before children
		Entity root = record.getRootEntity();
		InsertQueryNodeVisitor visitor = new InsertQueryNodeVisitor();
		root.traverse(visitor);
		BatchBindStep batch = visitor.getBatch();
		batch.execute();
	}

	private class InsertQueryNodeVisitor implements NodeVisitor {
		private BatchBindStep batch;
		
		public InsertQueryNodeVisitor() {
			Factory jf = getJooqFactory();
			InsertValuesStep<DataRecord> query = jf.insertInto(
					DATA, 
					DATA.ID,
					DATA.DEFINITION_ID, 
					DATA.RECORD_ID, 
					DATA.POSITION, 
					DATA.PARENT_ID,
					DATA.FIELD,
					DATA.VALUE,
					DATA.REMARKS,
					DATA.SYMBOL
				)
				.values(null, null, null, null, null, null, null, null, null);
			batch = jf.batch(query);
		}
		
		@Override
		public void visit(Node<? extends NodeDefinition> node, int idx) {
			insert(node, idx);
		}
		
		public BatchBindStep getBatch() {
			return batch;
		}
		
		private void insert(Node<?> node, int idx) {
			CollectRecord record = (CollectRecord) node.getRecord();
			Integer recordId = record.getId();
			Integer parentId = getParentId(node);
			NodeDefinition defn = node.getDefinition();
			Integer defnId = defn.getId();
			if ( defnId == null ) {
				throw new NullPointerException("Null schema object definition id");			
			}
			Integer id;
			if ( node instanceof Entity ) {
				id = addRecord(defnId, recordId, idx + 1, parentId, 1, null, null, null);
				node.setId(id);
			} else if ( node instanceof Attribute ) {
				addAttribute(defnId, recordId, idx + 1, parentId, (Attribute<?,?>) node);
			} else {
				throw new RuntimeException("Unknown node "+node.getClass());
			}
		}

		private void addAttribute(Integer defnId, Integer recordId, Integer position, Integer parentId, Attribute<?, ?> attribute) {
			for (int f = 0; f < attribute.getFieldCount(); f++) {
				Field<?> field = attribute.getField(f);
				Object value = field.getValue();
				String valueString = value == null ? null : value.toString();
				Character symbol = field.getSymbol();
				String symbolString = symbol == null ? null : symbol.toString();
				addRecord(defnId, recordId, position, parentId, f+1, valueString, field.getRemarks(), symbolString);
			}
		}
		
		private Integer addRecord(Integer defnId, Integer recordId, Integer idx, Integer parentId, Integer field, String value, String remarks, String symbol) {
			Factory jf = getJooqFactory();
			Integer id = jf.nextval(DATA_ID_SEQ).intValue();
			batch.bind(id, defnId, recordId, idx, parentId, field, value, remarks, symbol);
			return id;
		}
		
		private Integer getParentId(Node<?> node) {
			Integer parentId = null;
			Entity parent = node.getParent();
			if ( parent != null ) {
				parentId = parent.getId();
				if ( parentId == null ) {
					throw new IllegalStateException("Unsaved parent");
				}
			}
			return parentId;
		}
	}
	

	void load(CollectRecord record) throws DataInconsistencyException {
		// Fetch all data for one record
{'fraction_non_alphanumeric': 0.11966892746292677, 'fraction_numerical': 0.0011495574203931487, 'mean_word_length': 4.017301038062284, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, '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': '3438257', 'n_tokens_mistral': 3173, 'n_tokens_neox': 2749, 'n_words': 658}