All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.ugli.habanero.j.batch.Dataset Maven / Gradle / Ivy

package se.ugli.habanero.j.batch;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import javax.sql.DataSource;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import se.ugli.commons.Closeables;
import se.ugli.commons.Resource;
import se.ugli.habanero.j.HabaneroException;
import se.ugli.habanero.j.batch.BatchItem.BatchItemBuilder;
import se.ugli.habanero.j.metadata.MetaData;
import se.ugli.habanero.j.metadata.SqlType;

public class Dataset {

    private class SaxHandler extends DefaultHandler {

        private final Batch batch;
        private boolean started = false;
        private final Map> tableCache = new HashMap>();
        private final DataSource dataSource;

        public SaxHandler(final DataSource dataSource) {
            this.dataSource = dataSource;
            batch = new Batch(dataSource);
        }

        @Override
        public void endDocument() {
            try {
                batch.execute();
            }
            catch (final SQLException e) {
                throw new HabaneroException(e);
            }
        }

        @Override
        public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) {
            if (!started)
                started = true;
            else
                addToBatch(localName, attributes);
        }

        private void addToBatch(final String tableName, final Attributes attributes) {
            try {
                final BatchItemBuilder builder = new BatchItemBuilder();
                builder.appendSql("insert into ");
                builder.appendSql(tableName);
                builder.appendSql("(");
                final int numOfAttributes = attributes.getLength();
                for (int index = 0; index < numOfAttributes; index++) {
                    final String columnName = attributes.getLocalName(index);
                    builder.appendSql(columnName);
                    final String value = attributes.getValue(index);
                    builder.addArg(convertValue(tableName, columnName, value));
                    builder.appendSql(index < numOfAttributes - 1 ? "," : ")");
                }
                builder.appendSql(" values(");
                for (int index = 0; index < numOfAttributes; index++) {
                    builder.appendSql("?");
                    builder.appendSql(index < numOfAttributes - 1 ? "," : ")");
                }
                batch.add(builder.build());
            }
            catch (final SQLException e) {
                throw new HabaneroException(e);
            }
        }

        private Object convertValue(final String tableName, final String columnName, final String value) {
            final SqlType outParam = getType(tableName, columnName);
            if (outParam == SqlType.NUMERIC || outParam == SqlType.DECIMAL)
                return new BigInteger(value);
            else if (outParam == SqlType.BIT || outParam == SqlType.TINYINT || outParam == SqlType.SMALLINT || outParam == SqlType.INTEGER
                    || outParam == SqlType.BIGINT)
                return Long.parseLong(value);
            else if (outParam == SqlType.REAL || outParam == SqlType.FLOAT || outParam == SqlType.DOUBLE)
                return Double.parseDouble(value);
            else if (outParam == SqlType.BINARY || outParam == SqlType.VARBINARY || outParam == SqlType.LONGVARBINARY)
                return value.getBytes();
            return value;
        }

        private SqlType getType(final String tableName, final String columnName) {
            if (!tableCache.containsKey(tableName))
                tableCache.put(tableName, new HashMap());
            final Map columnCache = tableCache.get(tableName);
            if (!columnCache.containsKey(columnName)) {
                final Optional columnTypeOpt = MetaData.apply(dataSource).getColumnType(tableName, columnName);
                if (columnTypeOpt.isPresent())
                    columnCache.put(columnName, columnTypeOpt.get());
                else
                    throw new HabaneroException("Couldn't find type for " + tableName + "." + columnName);
            }
            return columnCache.get(columnName);
        }
    }

    public static Dataset apply(final DataSource dataSource) {
        return new Dataset(dataSource);
    }

    private final DataSource dataSource;

    private Dataset(final DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void exec(final File file) {
        InputStream resourceStream = null;
        try {
            resourceStream = new FileInputStream(file);
            exec(resourceStream);
        }
        catch (final FileNotFoundException e) {
            throw new HabaneroException(e);
        }
        finally {
            Closeables.close(resourceStream);
        }
    }

    public void exec(final Resource resource) {
        InputStream resourceStream = null;
        try {
            resourceStream = resource.getInputStream();
            exec(resourceStream);
        }
        finally {
            Closeables.close(resourceStream);
        }
    }

    public void exec(final InputStream inputStream) {
        final SaxHandler saxHandler = new SaxHandler(dataSource);
        try {
            createSaxParser().parse(inputStream, saxHandler);
        }
        catch (final SAXException e) {
            throw new HabaneroException(e);
        }
        catch (final IOException e) {
            throw new HabaneroException(e);
        }
        finally {
            saxHandler.batch.close();
        }
    }

    private SAXParser createSaxParser() {
        try {
            final SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setNamespaceAware(true);
            return factory.newSAXParser();
        }
        catch (final ParserConfigurationException e) {
            throw new HabaneroException(e);
        }
        catch (final SAXException e) {
            throw new HabaneroException(e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy