org.callimachusproject.sql.SqlTupleResult.java Source code

Java tutorial

Introduction

Here is the source code for org.callimachusproject.sql.SqlTupleResult.java

Source

/*
 * Copyright (c) 2013 3 Round Stones Inc., Some Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.callimachusproject.sql;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;

import org.apache.commons.codec.binary.Hex;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.XMLSchema;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.query.impl.MapBindingSet;

public final class SqlTupleResult implements TupleQueryResult {
    private final ValueFactory vf = ValueFactoryImpl.getInstance();
    private final ResultSet rs;
    private final Statement stmt;
    private final Connection conn;
    private final ResultSetMetaData md;
    private final DatatypeFactory df;
    private BindingSet next;

    public SqlTupleResult(ResultSet rs, Statement stmt, Connection conn)
            throws SQLException, DatatypeConfigurationException {
        this.rs = rs;
        this.stmt = stmt;
        this.conn = conn;
        md = rs.getMetaData();
        df = DatatypeFactory.newInstance();
    }

    @Override
    public void close() throws QueryEvaluationException {
        try {
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException e) {
            throw new QueryEvaluationException(e.toString(), e);
        }
    }

    @Override
    public List<String> getBindingNames() throws QueryEvaluationException {
        try {
            int n = md.getColumnCount();
            List<String> names = new ArrayList<>(n);
            for (int col = 1; col <= n; col++) {
                names.add(md.getColumnName(col));
            }
            return names;
        } catch (SQLException e) {
            throw new QueryEvaluationException(e.toString(), e);
        }
    }

    @Override
    public boolean hasNext() throws QueryEvaluationException {
        return next != null || (next = next()) != null;
    }

    @Override
    public synchronized BindingSet next() throws QueryEvaluationException {
        try {
            if (next != null)
                return next;
        } finally {
            next = null;
        }
        try {
            if (!rs.next())
                return null;
            int n = md.getColumnCount();
            MapBindingSet map = new MapBindingSet(n);
            for (int col = 1; col <= n; col++) {
                Value value = value(col);
                if (value != null) {
                    map.addBinding(md.getColumnName(col), value);
                }
            }
            return map;
        } catch (SQLException e) {
            throw new QueryEvaluationException(e.toString(), e);
        }
    }

    @Override
    public void remove() throws QueryEvaluationException {
        try {
            rs.deleteRow();
        } catch (SQLException e) {
            throw new QueryEvaluationException(e.toString(), e);
        }
    }

    private Value value(int col) throws SQLException {
        int type = md.getColumnType(col);
        String str = rs.getString(col);
        if (str == null)
            return null;
        switch (type) {
        case java.sql.Types.NULL:
            return null;
        case java.sql.Types.DATALINK:
            return vf.createURI(str);
        case java.sql.Types.BINARY:
        case java.sql.Types.VARBINARY:
        case java.sql.Types.BIT:
        case java.sql.Types.BLOB:
        case java.sql.Types.LONGVARBINARY:
        case java.sql.Types.JAVA_OBJECT:
            return vf.createLiteral(Hex.encodeHexString(rs.getBytes(col)), XMLSchema.HEXBINARY);
        case java.sql.Types.DECIMAL:
        case java.sql.Types.NUMERIC:
            return vf.createLiteral(str, XMLSchema.DECIMAL);
        case java.sql.Types.TINYINT:
        case java.sql.Types.SMALLINT:
        case java.sql.Types.INTEGER:
        case java.sql.Types.BIGINT:
            return vf.createLiteral(str, XMLSchema.INTEGER);
        case java.sql.Types.DOUBLE:
        case java.sql.Types.FLOAT:
        case java.sql.Types.REAL:
            return vf.createLiteral(str, XMLSchema.DOUBLE);
        case java.sql.Types.BOOLEAN:
            return vf.createLiteral(rs.getBoolean(col));
        case java.sql.Types.DATE:
            GregorianCalendar date = new GregorianCalendar();
            date.setTime(rs.getDate(col));
            date.clear(Calendar.AM_PM);
            date.clear(Calendar.HOUR);
            date.clear(Calendar.HOUR_OF_DAY);
            date.clear(Calendar.MINUTE);
            date.clear(Calendar.SECOND);
            date.clear(Calendar.MILLISECOND);
            return vf.createLiteral(df.newXMLGregorianCalendar(date));
        case java.sql.Types.TIME:
            GregorianCalendar time = new GregorianCalendar();
            time.setTime(rs.getTime(col));
            time.clear(Calendar.ERA);
            time.clear(Calendar.YEAR);
            time.clear(Calendar.MONTH);
            time.clear(Calendar.WEEK_OF_YEAR);
            time.clear(Calendar.WEEK_OF_MONTH);
            time.clear(Calendar.DATE);
            time.clear(Calendar.DAY_OF_MONTH);
            time.clear(Calendar.DAY_OF_YEAR);
            time.clear(Calendar.DAY_OF_WEEK);
            time.clear(Calendar.DAY_OF_WEEK_IN_MONTH);
            return vf.createLiteral(df.newXMLGregorianCalendar(time));
        case java.sql.Types.TIMESTAMP:
            return vf.createLiteral(rs.getTimestamp(col));
        case java.sql.Types.SQLXML:
            return vf.createLiteral(str, RDF.XMLLITERAL);
        case java.sql.Types.ARRAY:
        case java.sql.Types.CHAR:
        case java.sql.Types.CLOB:
        case java.sql.Types.DISTINCT:
        case java.sql.Types.LONGNVARCHAR:
        case java.sql.Types.NCHAR:
        case java.sql.Types.NCLOB:
        case java.sql.Types.NVARCHAR:
        case java.sql.Types.OTHER:
        case java.sql.Types.REF:
        case java.sql.Types.ROWID:
        case java.sql.Types.STRUCT:
        case java.sql.Types.VARCHAR:
        default:
            return vf.createLiteral(str);
        }
    }
}