Package com.aneeshpu.dpdeppop.schema

Source Code of com.aneeshpu.dpdeppop.schema.Record

package com.aneeshpu.dpdeppop.schema;

import com.aneeshpu.dpdeppop.query.Query;
import com.aneeshpu.dpdeppop.query.QueryFactory;
import org.apache.log4j.Logger;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

public class Record {
    public static final Logger LOG = Logger.getLogger(Record.class);

    public static final String PRIMARY_KEY_TABLE_NAME = "pktable_name";
    public static final String PRIMARY_KEY_COLUMN_NAME = "pkcolumn_name";
    public static final String FOREIGN_KEY_COLUMN_NAME = "fkcolumn_name";
    public static final String COLUMN_NAME = "column_name";

    private final String name;
    private final Connection connection;
    private final Map<String, Map<String, Object>> preassignedValues;
    private final QueryFactory queryFactory;
    private Map<String, Record> parentTables;
    private final Map<String, Column> columns;
    private final ColumnCreationStrategy columnCreationStrategy;

    public Record(String name, final Connection connection, final Map<String, Map<String, Object>> preassignedValues, final ColumnCreationStrategy columnCreationStrategy, final QueryFactory queryFactory) {
        this.name = name;
        this.connection = connection;
        this.preassignedValues = preassignedValues;
        this.queryFactory = queryFactory;
        this.columnCreationStrategy = columnCreationStrategy;

        columns = new HashMap<String, Column>();
    }

    private Record initialize(final Map<String, Record> parentTables) throws SQLException {

        try {
            this.parentTables = populateParents(parentTables);
            final Map<String, Column> stringColumnHashMap = columnCreationStrategy.populateColumns(this);
            columns.putAll(stringColumnHashMap);

            return this;

        } catch (SQLException e) {
            LOG.error(e);

            throw e;
        }
    }

    public String tableName() {
        return name;
    }

    public Column getColumn(final String columnName) {
        return columns.get(columnName);
    }

    private Map<String, Record> populateParents(final Map<String, Record> parentTables) throws SQLException {
        final ResultSet importedKeysResultSet = connection.getMetaData().getImportedKeys(null, null, name);

        while (importedKeysResultSet.next()) {
            final String primaryKeyTableName = importedKeysResultSet.getString(PRIMARY_KEY_TABLE_NAME);
            final String foreignKeyColumnName = importedKeysResultSet.getString(FOREIGN_KEY_COLUMN_NAME);

            if (parentTableIsPreassigned(foreignKeyColumnName) || parentTables.containsKey(primaryKeyTableName)) {
                if (LOG.isInfoEnabled()) {
                    LOG.info(foreignKeyColumnName + " is either pre-assigned or " + primaryKeyTableName + " has already been initialized");
                }
                continue;
            }

            parentTables.put(primaryKeyTableName, new RecordBuilder().withQueryFactory(connection).setName(primaryKeyTableName).setConnection(connection).setPreassignedValues(preassignedValues).setColumnCreationStrategy(columnCreationStrategy).createRecord().initialize(parentTables));
        }

        return parentTables;

    }

    private boolean parentTableIsPreassigned(final String foreignKeyColumnName) {
        final Map<String, Object> preassignedCols = preassignedValues.get(name);

        if (preassignedCols == null || preassignedCols.isEmpty()) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("table " + name + " has no preassigned keys.");
            }

            return false;
        }

        return preassignedCols.containsKey(foreignKeyColumnName);
    }

    private Map<String, Record> parents() {
        return parentTables;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final Record record = (Record) o;

        if (!name.equals(record.name)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public String toString() {
        return name;
    }

    public Map<String, Column> columns() {
        return columns;
    }

    public Map<String, Record> populate(final boolean onlyPopulateParentTables) throws SQLException {

        initialize(new LinkedHashMap<String, Record>());

        final Map<String, Record> tables = new HashMap<String, Record>();
        insertDefaultValuesIntoParentTables(tables);

        if (onlyPopulateParentTables) {
            if (LOG.isInfoEnabled()) {
                LOG.info("Not populating table " + name + " as onlyPopulateParentTables = " + onlyPopulateParentTables);
            }
            return tables;
        }

        insertDefaultValuesIntoCurrentTable();

        tables.put(name, this);
        return tables;
    }

    private void insertDefaultValuesIntoParentTables(final Map<String, Record> tables) throws SQLException {

        for (Map.Entry<String, Record> entry : parentTables.entrySet()) {

            final Record parentRecord = entry.getValue();
            parentRecord.insertDefaultValuesIntoCurrentTable();
            tables.put(parentRecord.name, parentRecord);

            tables.putAll(parentTables);
        }
    }

    private String insertDefaultValuesIntoCurrentTable() throws SQLException {

        final ResultSet generatedKeys = queryFactory.generateInsertQuery(columns, this.preassignedValues, this).execute();
        setGeneratedValuesOnColumns(generatedKeys, getColumnsWithGeneratedValues());

        return queryFactory.generateInsertQuery(columns, this.preassignedValues, this).toString();
    }

    private void setGeneratedValuesOnColumns(final ResultSet generatedKeys, final Map<String, Column> columnsWithGeneratedValues) throws SQLException {
        while (generatedKeys.next()) {
            for (Map.Entry<String, Column> entrySet : columnsWithGeneratedValues.entrySet()) {
                final Column column = entrySet.getValue();
                column.populateGeneratedValue(generatedKeys);
            }
        }
    }

    private Map<String, Column> getColumnsWithGeneratedValues() {
        final Map<String, Column> columnsWithGeneratedValues = new HashMap<String, Column>();
        for (Map.Entry<String, Column> entrySet : columns.entrySet()) {

            if (entrySet.getValue().isAutoIncrement()) {
                columnsWithGeneratedValues.put(entrySet.getKey(), entrySet.getValue());
            }
        }

        return columnsWithGeneratedValues;
    }

    public String name() {
        return name;
    }

    public List<String> getPrimaryKeys() throws SQLException {
        final ResultSet primaryKeysResultSet = connection.getMetaData().getPrimaryKeys(null, null, name);

        final List<String> primaryKeys = new ArrayList<String>();
        while (primaryKeysResultSet.next()) {
            final String primaryKey = primaryKeysResultSet.getString(Record.COLUMN_NAME);
            primaryKeys.add(primaryKey);
        }

        return primaryKeys;

    }

    public void delete() throws SQLException {
        deleteSelf();

        deleteParents();
    }

    private void deleteSelf() throws SQLException {
        final Query deleteQueryQuery = queryFactory.generateDeleteQuery(getPrimaryKeyColumn(), this.preassignedValues, this);
        deleteQueryQuery.execute();
    }

    private void deleteParents() throws SQLException {
        final ListIterator<Map.Entry<String, Record>> entryListIterator = new ArrayList<Map.Entry<String, Record>>(parentTables.entrySet()).listIterator(parentTables.size());
        while (entryListIterator.hasPrevious()) {
            final Map.Entry<String, Record> parentTableEntrySet = entryListIterator.previous();
            parentTableEntrySet.getValue().deleteSelf();
        }
    }

    private Column getPrimaryKeyColumn() {
        for (Map.Entry<String, Column> stringColumnEntry : columns.entrySet()) {
            final Column column = stringColumnEntry.getValue();
            if (column.isPrimaryKey()) return column;
        }

        throw new NoPrimaryKeyFoundException();

    }

    public boolean isPrimaryKey(final String columnName) throws SQLException {
        final List<String> primaryKeys = getPrimaryKeys();
        return primaryKeys.contains(columnName);
    }

    Map<String, ColumnTable> foreignKeyTableMap() throws SQLException {

        final ResultSet crossReference = connection.getMetaData().getCrossReference(null, null, null, null, null, tableName());

        final Map<String, ColumnTable> foreignKeys = new HashMap<String, ColumnTable>();
        while (crossReference.next()) {

            final String primaryKeyTableName = crossReference.getString(PRIMARY_KEY_TABLE_NAME);
            final String primaryKeyColName = crossReference.getString(PRIMARY_KEY_COLUMN_NAME);
            final String foreignKeyColumnName = crossReference.getString(FOREIGN_KEY_COLUMN_NAME);


            final Record primaryRecord = this.parentTables.get(primaryKeyTableName);

            foreignKeys.put(foreignKeyColumnName, new ColumnTable(primaryKeyColName, primaryRecord));
        }


        return foreignKeys;
    }
}
TOP

Related Classes of com.aneeshpu.dpdeppop.schema.Record

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.