You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/04/05 21:34:02 UTC

svn commit: r1465101 - in /jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc: ./ results/ results/metadata/ results/metadata/columns/

Author: rvesse
Date: Fri Apr  5 19:34:01 2013
New Revision: 1465101

URL: http://svn.apache.org/r1465101
Log:
More infrastructure towards configurable JDBC compatibility

Added:
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DateColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DecimalColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DoubleColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/FloatColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/IntegerColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/NumericColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/TimeColumn.java
Modified:
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JdbcCompatibility.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaResultSet.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/SelectResultsMetadata.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/BooleanColumn.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/ColumnInfo.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/SparqlColumnInfo.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/StringColumn.java

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JdbcCompatibility.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JdbcCompatibility.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JdbcCompatibility.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JdbcCompatibility.java Fri Apr  5 19:34:01 2013
@@ -18,9 +18,22 @@
 
 package org.apache.jena.jdbc;
 
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
 import java.sql.Types;
 
+import org.apache.jena.jdbc.results.metadata.columns.BooleanColumn;
+import org.apache.jena.jdbc.results.metadata.columns.ColumnInfo;
+import org.apache.jena.jdbc.results.metadata.columns.DateColumn;
+import org.apache.jena.jdbc.results.metadata.columns.DecimalColumn;
+import org.apache.jena.jdbc.results.metadata.columns.DoubleColumn;
+import org.apache.jena.jdbc.results.metadata.columns.FloatColumn;
+import org.apache.jena.jdbc.results.metadata.columns.IntegerColumn;
+import org.apache.jena.jdbc.results.metadata.columns.StringColumn;
+import org.apache.jena.jdbc.results.metadata.columns.TimeColumn;
+
 import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.vocabulary.XSD;
 
 /**
  * <p>
@@ -47,11 +60,14 @@ public class JdbcCompatibility {
     /**
      * Constant for low JDBC compatibility level
      * <p>
-     * This is the level you should use when you know you are accessing a SPARQL source and are able to cope with the Jena/ARQ representation of RDF terms natively.
+     * This is the level you should use when you know you are accessing a SPARQL
+     * source and are able to cope with the Jena/ARQ representation of RDF terms
+     * natively.
      * </p>
      * <h3>Behavior Specifies</h3>
      * <ul>
-     * <li>Column Typing - All result set columns are reported as being as typed as {@link Types#JAVA_OBJECT} and Java type is the ARQ {@link Node} type.</li>
+     * <li>Column Typing - All result set columns are reported as being as typed
+     * as {@link Types#JAVA_OBJECT} and Java type is the ARQ {@link Node} type.</li>
      * </ul>
      */
     public static final int LOW = 1;
@@ -59,11 +75,13 @@ public class JdbcCompatibility {
     /**
      * Constant for medium JDBC compatibility level
      * <p>
-     * This is the default compatibility level, we will make some effort to be compatible with JDBC but these efforts will not be perfect.
+     * This is the default compatibility level, we will make some effort to be
+     * compatible with JDBC but these efforts will not be perfect.
      * </p>
      * <h3>Behavior Specifics</h3>
      * <ul>
-     * <li>Column Typing - All result set columns are reported as being as typed as {@link Types#NVARCHAR} and Java type is {@link String}.</li>
+     * <li>Column Typing - All result set columns are reported as being as typed
+     * as {@link Types#NVARCHAR} and Java type is {@link String}.</li>
      * </ul>
      */
     public static final int MEDIUM = 5;
@@ -71,23 +89,29 @@ public class JdbcCompatibility {
     /**
      * Constant for high JDBC compatibility level
      * <p>
-     * This is the highest compatibility level, we will do our best to be compatible with JDBC however these efforts may still not be perfect.
+     * This is the highest compatibility level, we will do our best to be
+     * compatible with JDBC however these efforts may still not be perfect.
      * </p>
      * <h3>Behavior Specifics</h3>
      * <ul>
-     * <li>Column Typing - Result set columns are typed by inspecting the first row of the data so native JDBC types like {@link Types#INTEGER} and so forth may be reported depending on the query.</li>
+     * <li>Column Typing - Result set columns are typed by inspecting the first
+     * row of the data so native JDBC types like {@link Types#INTEGER} and so
+     * forth may be reported depending on the query.</li>
      * </ul>
      */
     public static final int HIGH = 9;
-    
+
     /**
      * Constant for default JDBC compatibility which is set to {@link #MEDIUM}
      */
     public static final int DEFAULT = MEDIUM;
-    
+
     /**
-     * Normalizes the compatibility level given to be within the acceptable range of 1-9
-     * @param level Level
+     * Normalizes the compatibility level given to be within the acceptable
+     * range of 1-9
+     * 
+     * @param level
+     *            Level
      * @return Normalized level
      */
     public static int normalizeLevel(int level) {
@@ -99,24 +123,128 @@ public class JdbcCompatibility {
             return level;
         }
     }
-    
+
     /**
-     * Returns whether a result set is expected to determine the column types from the returned data
-     * @param level Desired compatibility level
+     * Returns whether a result set is expected to determine the column types
+     * from the returned data
+     * 
+     * @param level
+     *            Desired compatibility level
      * @return True if column types should be detected, false otherwise
      */
     public static boolean shouldDetectColumnTypes(int level) {
         level = normalizeLevel(level);
-        return level > MEDIUM;
+        return level == HIGH;
     }
-    
+
     /**
-     * Returns whether a result set is expected to type returned columns as strings
-     * @param level Desired compatibility level
+     * Returns whether a result set is expected to type returned columns as
+     * strings
+     * 
+     * @param level
+     *            Desired compatibility level
      * @return True if columns should be typed as string, false otherwise
      */
     public static boolean shouldTypeColumnsAsString(int level) {
         level = normalizeLevel(level);
-        return level >= MEDIUM;
+        return level >= MEDIUM && level < HIGH;
+    }
+
+    /**
+     * Detects the column type information based on an example value
+     * 
+     * @param var
+     *            Variable Name i.e. the column label
+     * @param value
+     *            Example value
+     * @param allowsNulls
+     *            Whether the result set we are detecting the type for allows
+     *            null values in this column
+     * @return Column Information
+     * @throws SQLException
+     *             Thrown if the column type cannot be detected, this should
+     *             only occur if you state that the column does not allow nulls
+     *             and then provide a null example value
+     */
+    public static ColumnInfo detectColumnType(String var, Node value, boolean allowsNulls) throws SQLException {
+        if (allowsNulls && value == null) {
+            // If we are allowing nulls and the value is null just type the
+            // column as string
+            return new StringColumn(var, ResultSetMetaData.columnNullable);
+        } else if (!allowsNulls && value == null) {
+            throw new SQLException("Unable to determine column type, column is non-nullable but example value is null");
+        } else {
+            // We know we have a non-null value so now we need to determine the
+            // column type appropriately
+            int nullable = allowsNulls ? ResultSetMetaData.columnNullable : ResultSetMetaData.columnNoNulls;
+            if (value.isBlank()) {
+                // Type blank nodes as strings
+                return new StringColumn(var, nullable);
+            } else if (value.isURI()) {
+                // Type URIs as strings
+                // TODO: Does JDBC have a URL type?
+                return new StringColumn(var, nullable);
+            } else if (value.isLiteral()) {
+                // Literals will be typed based on the declared data type where
+                // applicable
+                String dtUri = value.getLiteralDatatypeURI();
+                if (dtUri != null) {
+                    // Is a typed literal
+                    return selectColumnType(var, dtUri, nullable);
+                } else {
+                    // Untyped literals are typed as strings
+                    return new StringColumn(var, nullable);
+                }
+            } else {
+                // Anything else we treat as a string
+                return new StringColumn(var, nullable);
+            }
+        }
+    }
+
+    /**
+     * Select the column type based on the data type URI
+     * @param var Variable Name i.e. the column label
+     * @param dtUri Data type URI
+     * @param nullable Whether the column is nullable
+     * @return Column type
+     * @throws SQLException
+     */
+    private static ColumnInfo selectColumnType(String var, String dtUri, int nullable) throws SQLException {
+        if (dtUri.equals(XSD.date.toString()) || dtUri.equals(XSD.dateTime.toString())) {
+            // Date column
+            return new DateColumn(var, nullable);
+        } else if (dtUri.equals(XSD.decimal.toString())) {
+            // Decimal column
+            return new DecimalColumn(var, nullable);
+        } else if (dtUri.equals(XSD.duration.toString())) {
+            // JDBC has no notion of durations so return as a string
+            return new StringColumn(var, nullable);
+        } else if (dtUri.equals(XSD.integer.toString()) || dtUri.equals(XSD.xint.toString())
+                || dtUri.equals(XSD.xlong.toString()) || dtUri.equals(XSD.xshort.toString())) {
+            // Integer column
+            return new IntegerColumn(var, nullable, true);
+        } else if (dtUri.equals(XSD.unsignedInt.toString()) || dtUri.equals(XSD.unsignedLong.toString()) || dtUri.equals(XSD.unsignedShort.toString())) {
+            // Unsigned Integer column
+            return new IntegerColumn(var, nullable, false);
+        } else if (dtUri.equals(XSD.time.toString())) {
+            // Time column
+            return new TimeColumn(var, nullable);
+        } else if (dtUri.equals(XSD.xboolean.toString())) {
+            // Boolean column
+            return new BooleanColumn(var, nullable);
+        } else if (dtUri.equals(XSD.xdouble.toString())) {
+            // Double column
+            return new DoubleColumn(var, nullable);
+        } else if (dtUri.equals(XSD.xfloat.toString())) {
+            // Float column
+            return new FloatColumn(var, nullable);
+        } else if (dtUri.equals(XSD.xstring.toString())) {
+            // String column
+            return new StringColumn(var, nullable);
+        } else {
+            // Anything else we'll treat as a String
+            return new StringColumn(var, nullable);
+        }
     }
 }

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaResultSet.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaResultSet.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaResultSet.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/JenaResultSet.java Fri Apr  5 19:34:01 2013
@@ -41,6 +41,8 @@ import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.Map;
 
+import org.apache.jena.jdbc.JdbcCompatibility;
+import org.apache.jena.jdbc.connections.JenaConnection;
 import org.apache.jena.jdbc.statements.JenaStatement;
 import org.apache.jena.jdbc.utils.JenaJdbcNodeUtils;
 
@@ -54,11 +56,12 @@ import com.hp.hpl.jena.graph.Node;
 public abstract class JenaResultSet implements ResultSet {
 
     private static final int DEFAULT_HOLDABILITY = ResultSet.CLOSE_CURSORS_AT_COMMIT;
-    
+
     private SQLWarning warnings;
-    private Statement statement;
+    private JenaStatement statement;
     private boolean wasNull = false;
     private int holdability = DEFAULT_HOLDABILITY;
+    private int compatibilityLevel = JdbcCompatibility.DEFAULT;
 
     /**
      * Creates a new result set
@@ -72,6 +75,28 @@ public abstract class JenaResultSet impl
         if (statement == null)
             throw new SQLException("Statement for a Result Set cannot be null");
         this.statement = statement;
+        this.compatibilityLevel = JdbcCompatibility.normalizeLevel(this.statement.getJenaConnection().getJdbcCompatibilityLevel());
+    }
+
+    /**
+     * Gets the {@link JenaStatement} associated with the result set
+     * 
+     * @return Jena Statement
+     */
+    public JenaStatement getJenaStatement() {
+        return this.statement;
+    }
+
+    /**
+     * Gets the JDBC compatibility level to use for the result set, this will
+     * reflect the compatibility level at the time the result set was created
+     * not necessarily the current compatibility level of the backing
+     * {@link JenaConnection}
+     * 
+     * @return JDBC compatibility level, see {@link JdbcCompatibility}
+     */
+    public int getJdbcCompatibilityLevel() {
+        return this.compatibilityLevel;
     }
 
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
@@ -93,15 +118,15 @@ public abstract class JenaResultSet impl
     public void deleteRow() throws SQLException {
         throw new SQLFeatureNotSupportedException("Jena JDBC Result Sets are read-only");
     }
-    
+
     public final int getHoldability() throws SQLException {
         return this.holdability;
     }
-    
+
     public final int getConcurrency() throws SQLException {
         return ResultSet.CONCUR_READ_ONLY;
     }
-    
+
     public abstract ResultSetMetaData getMetaData() throws SQLException;
 
     // Get Methods for things we do support
@@ -399,7 +424,7 @@ public abstract class JenaResultSet impl
     public InputStream getAsciiStream(String columnLabel) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
-    
+
     @Deprecated
     public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
         throw new SQLFeatureNotSupportedException();
@@ -453,7 +478,7 @@ public abstract class JenaResultSet impl
     public String getCursorName() throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
-    
+
     public Date getDate(int columnIndex, Calendar cal) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
@@ -477,7 +502,7 @@ public abstract class JenaResultSet impl
     public NClob getNClob(String columnLabel) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
-    
+
     public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
@@ -513,7 +538,7 @@ public abstract class JenaResultSet impl
     public Statement getStatement() throws SQLException {
         return this.statement;
     }
-    
+
     public Time getTime(int columnIndex, Calendar cal) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
@@ -521,7 +546,7 @@ public abstract class JenaResultSet impl
     public Time getTime(String columnLabel, Calendar cal) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }
-    
+
     public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
         throw new SQLFeatureNotSupportedException();
     }

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java Fri Apr  5 19:34:01 2013
@@ -22,6 +22,7 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.Iterator;
 
+import org.apache.jena.atlas.iterator.PeekIterator;
 import org.apache.jena.atlas.lib.Closeable;
 import org.apache.jena.jdbc.results.metadata.TripleResultsMetadata;
 import org.apache.jena.jdbc.statements.JenaStatement;
@@ -39,7 +40,7 @@ public class TripleIteratorResults exten
 
     private TripleResultsMetadata metadata;
 
-    private Iterator<Triple> triples;
+    private PeekIterator<Triple> triples;
 
     /**
      * Creates a new result set which is backed by a triple iterator
@@ -59,8 +60,8 @@ public class TripleIteratorResults exten
         super(statement, qe, commit);
         if (ts == null)
             throw new SQLException("Triple Iterator cannot be null");
-        this.triples = ts;
-        this.metadata = new TripleResultsMetadata(this);
+        this.triples = PeekIterator.create(ts);
+        this.metadata = new TripleResultsMetadata(this, this.triples);
     }
 
     public int findColumn(String columnLabel) throws SQLException {

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/SelectResultsMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/SelectResultsMetadata.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/SelectResultsMetadata.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/SelectResultsMetadata.java Fri Apr  5 19:34:01 2013
@@ -19,48 +19,98 @@
 package org.apache.jena.jdbc.results.metadata;
 
 import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Types;
 import java.util.List;
 
+import org.apache.jena.jdbc.JdbcCompatibility;
 import org.apache.jena.jdbc.results.JenaResultSet;
 import org.apache.jena.jdbc.results.SelectResults;
 import org.apache.jena.jdbc.results.metadata.columns.ColumnInfo;
+import org.apache.jena.jdbc.results.metadata.columns.SparqlColumnInfo;
 import org.apache.jena.jdbc.results.metadata.columns.StringColumn;
 
 import com.hp.hpl.jena.query.ResultSet;
 import com.hp.hpl.jena.query.ResultSetFactory;
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.engine.binding.Binding;
 import com.hp.hpl.jena.sparql.resultset.ResultSetPeekable;
 
 /**
- * Result Set Metadata for {@link SelectResults} instances 
- *
+ * Result Set Metadata for {@link SelectResults} instances
+ * 
  */
 public class SelectResultsMetadata extends JenaResultsMetadata {
 
     @SuppressWarnings("unused")
     private ResultSetPeekable innerResults;
-        
+
     /**
      * Creates new SELECT results metadata
-     * @param results JDBC result set
-     * @param rset Underlying SPARQL results
-     * @param columns Columns
-     * @throws SQLException 
+     * 
+     * @param results
+     *            JDBC result set
+     * @param rset
+     *            Underlying SPARQL results
+     * @throws SQLException
      */
     public SelectResultsMetadata(JenaResultSet results, ResultSetPeekable rset) throws SQLException {
         super(results, makeColumns(results, rset));
         this.innerResults = rset;
     }
-    
+
+    /**
+     * Creates new SELECT results metadata
+     * 
+     * @param results
+     *            JDBC result set
+     * @param rset
+     *            Underlying SPARQL results
+     * @throws SQLException
+     */
     public SelectResultsMetadata(JenaResultSet results, ResultSet rset) throws SQLException {
         this(results, ResultSetFactory.makePeekable(rset));
     }
-    
+
+    /**
+     * Makes column information for SELECT results 
+     * @param results Result Set
+     * @param rset Underlying SPARQL results
+     * @return Column information
+     * @throws SQLException Thrown if the column information cannot be created
+     */
     private static ColumnInfo[] makeColumns(JenaResultSet results, ResultSetPeekable rset) throws SQLException {
         List<String> vars = rset.getResultVars();
         ColumnInfo[] columns = new ColumnInfo[vars.size()];
         
+        int level = JdbcCompatibility.normalizeLevel(results.getJdbcCompatibilityLevel());
+        boolean columnsAsStrings = JdbcCompatibility.shouldTypeColumnsAsString(level);
+        boolean columnsDetected = JdbcCompatibility.shouldDetectColumnTypes(level);
+        
+        Binding b = null;
+        if (columnsDetected) {
+            if (rset.hasNext()) {
+                b = rset.peekBinding();
+            } else {
+                // If we were supposed to detect columns but there is no data available then we will just fallback to typing everything as strings
+                columnsAsStrings = true;
+                columnsDetected = false;
+            }
+        }
+        
         for (int i = 0; i < columns.length; i++) {
-            columns[i] = new StringColumn(vars.get(i), columnNullable);
+            if (!columnsAsStrings && !columnsDetected) {
+                // Low compatibility, report columns as being typed as JAVA_OBJECT with ARQ Node as the column class
+                columns[i] = new SparqlColumnInfo(vars.get(i), Types.JAVA_OBJECT, columnNullable);
+            } else if (columnsAsStrings) {
+                // Medium compatibility, report columns as being typed as NVARChar with String as the column class
+                columns[i] = new StringColumn(vars.get(i), columnNullable);
+            } else if (columnsDetected) {
+                // High compatibility, detect columns types based on first row of results
+                columns[i] = JdbcCompatibility.detectColumnType(vars.get(i), b.get(Var.alloc(vars.get(i))), true);
+            } else {
+                throw new SQLFeatureNotSupportedException("Unknown JDBC compatibility level was set");
+            }
         }
         
         return columns;

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java Fri Apr  5 19:34:01 2013
@@ -18,17 +18,25 @@
 
 package org.apache.jena.jdbc.results.metadata;
 
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Types;
+import java.util.Iterator;
 
+import org.apache.jena.atlas.iterator.PeekIterator;
+import org.apache.jena.jdbc.JdbcCompatibility;
 import org.apache.jena.jdbc.results.JenaResultSet;
 import org.apache.jena.jdbc.results.TripleIteratorResults;
 import org.apache.jena.jdbc.results.metadata.columns.ColumnInfo;
+import org.apache.jena.jdbc.results.metadata.columns.SparqlColumnInfo;
 import org.apache.jena.jdbc.results.metadata.columns.StringColumn;
 
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
+
 /**
  * Result set metadata for {@link TripleIteratorResults} instances
- *
+ * 
  */
 public class TripleResultsMetadata extends JenaResultsMetadata {
 
@@ -48,27 +56,98 @@ public class TripleResultsMetadata exten
      * Constant for the number of columns in triple results
      */
     public static final int NUM_COLUMNS = 3;
-    
+
+    /**
+     * Internal constant for the column names for triple result columns
+     */
+    private static final String[] COLUMN_NAMES = new String[] { COLUMN_LABEL_SUBJECT, COLUMN_LABEL_PREDICATE, COLUMN_LABEL_OBJECT };
+
     /**
      * Gets the columns for ASK results
+     * 
      * @return Column Information
      * @throws SQLException
      */
-    private static ColumnInfo[] makeColumns(JenaResultSet results) throws SQLException {
+    private static ColumnInfo[] makeColumns(JenaResultSet results, PeekIterator<Triple> ts) throws SQLException {
         ColumnInfo[] columns = new ColumnInfo[NUM_COLUMNS];
-        columns[0] = new StringColumn(COLUMN_LABEL_SUBJECT, ResultSetMetaData.columnNoNulls);
-        columns[1] = new StringColumn(COLUMN_LABEL_PREDICATE, ResultSetMetaData.columnNoNulls);
-        columns[2] = new StringColumn(COLUMN_LABEL_OBJECT, ResultSetMetaData.columnNoNulls);
+
+        int level = JdbcCompatibility.normalizeLevel(results.getJdbcCompatibilityLevel());
+        boolean columnsAsStrings = JdbcCompatibility.shouldTypeColumnsAsString(level);
+        boolean columnsDetected = JdbcCompatibility.shouldDetectColumnTypes(level);
+
+        Triple t = null;
+        if (columnsDetected) {
+            if (ts.hasNext()) {
+                t = ts.peek();
+            } else {
+                // If we were supposed to detect columns but there is no data
+                // available then we will just fallback to typing everything as
+                // strings
+                columnsAsStrings = true;
+                columnsDetected = false;
+            }
+        }
+
+        for (int i = 0; i < columns.length; i++) {
+            if (!columnsAsStrings && !columnsDetected) {
+                // Low compatibility, report columns as being typed as
+                // JAVA_OBJECT with ARQ Node as the column class
+                columns[i] = new SparqlColumnInfo(COLUMN_NAMES[i], Types.JAVA_OBJECT, columnNoNulls);
+            } else if (columnsAsStrings) {
+                // Medium compatibility, report columns as being typed as
+                // NVARChar with String as the column class
+                columns[i] = new StringColumn(COLUMN_NAMES[i], columnNoNulls);
+            } else if (columnsDetected) {
+                // High compatibility, detect columns types based on first row
+                // of results
+                columns[i] = JdbcCompatibility.detectColumnType(COLUMN_NAMES[i], getValue(t, i), false);
+            } else {
+                throw new SQLFeatureNotSupportedException("Unknown JDBC compatibility level was set");
+            }
+        }
+
         return columns;
     }
-    
+
+    private static Node getValue(Triple t, int i) {
+        switch (i) {
+        case 0:
+            return t.getSubject();
+        case 1:
+            return t.getPredicate();
+        case 2:
+            return t.getObject();
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
+     * 
+     * @param results
+     *            Result Set
+     * @param ts
+     *            Triple iterator
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
+     */
+    public TripleResultsMetadata(JenaResultSet results, PeekIterator<Triple> ts) throws SQLException {
+        super(results, makeColumns(results, ts));
+    }
+
     /**
      * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
-     * @param results Result Set
-     * @throws SQLException Thrown if the metadata cannot be created
+     * 
+     * @param results
+     *            Result Set
+     * @param ts
+     *            Triple iterator
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
      */
-    public TripleResultsMetadata(JenaResultSet results) throws SQLException {
-        super(results, makeColumns(results));
+    public TripleResultsMetadata(JenaResultSet results, Iterator<Triple> ts) throws SQLException {
+        this(results, PeekIterator.create(ts));
     }
 
 }

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/BooleanColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/BooleanColumn.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/BooleanColumn.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/BooleanColumn.java Fri Apr  5 19:34:01 2013
@@ -18,12 +18,21 @@
 
 package org.apache.jena.jdbc.results.metadata.columns;
 
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Types;
 
+/**
+ * Boolean column information
+ *
+ */
 public class BooleanColumn extends SparqlColumnInfo {
 
+    /**
+     * Creates a new boolean column
+     * @param label Label
+     * @param nullable Nullability
+     * @throws SQLException
+     */
     public BooleanColumn(String label, int nullable) throws SQLException {
         super(label, Types.BOOLEAN, nullable);
         this.setClassName(Boolean.class.getCanonicalName());

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/ColumnInfo.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/ColumnInfo.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/ColumnInfo.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/ColumnInfo.java Fri Apr  5 19:34:01 2013
@@ -25,7 +25,7 @@ import java.sql.Types;
 import com.hp.hpl.jena.graph.Node;
 
 /**
- * Helper class for representing column information
+ * Abstract class for representing column information
  * 
  */
 public abstract class ColumnInfo {
@@ -40,6 +40,8 @@ public abstract class ColumnInfo {
      * 
      * @param label
      *            Column Label
+     * @param type
+     *            JDBC Type
      * @throws SQLException
      */
     public ColumnInfo(String label, int type) throws SQLException {
@@ -49,97 +51,214 @@ public abstract class ColumnInfo {
         this.type = type;
     }
 
+    /**
+     * Gets the column label
+     * 
+     * @return Label
+     */
     public final String getLabel() {
         return this.label;
     }
 
+    /**
+     * Gets the class name for the column
+     * 
+     * @return Class name
+     */
     public final String getClassName() {
         return this.className;
     }
 
+    /**
+     * Sets the class name for the column
+     * 
+     * @param className
+     *            Class name
+     */
     protected void setClassName(String className) {
         this.className = className;
     }
 
+    /**
+     * Gets the display size for the column
+     * 
+     * @return Display size
+     */
     public final int getDisplaySize() {
         return this.displaySize;
     }
 
-    protected final  void setDisplaySize(int size) {
+    /**
+     * Sets the display size for the column
+     * 
+     * @param size
+     *            Display size
+     */
+    protected final void setDisplaySize(int size) {
         this.displaySize = size;
     }
 
+    /**
+     * Gets the JDBC type for the column
+     * 
+     * @return JDBC type, a value from the constants in {@link Types}
+     */
     public final int getType() {
         return this.type;
     }
 
+    /**
+     * Gets the underlying database type name
+     * 
+     * @return Type name
+     */
     public final String getTypeName() {
         return this.typeName;
     }
 
+    /**
+     * Sets the underying database type name
+     * 
+     * @param typeName
+     *            Type name
+     */
     protected final void setTypeName(String typeName) {
         this.typeName = typeName;
     }
 
+    /**
+     * Gets the precision
+     * 
+     * @return Precision
+     */
     public final int getPrecision() {
         return this.precision;
     }
 
+    /**
+     * Sets the precision
+     * 
+     * @param precision
+     *            Precision
+     */
     protected final void setPrecision(int precision) {
         this.precision = precision;
     }
 
+    /**
+     * Gets the scale
+     * 
+     * @return Scale
+     */
     public final int getScale() {
         return this.scale;
     }
 
+    /**
+     * Sets the scale
+     * 
+     * @param scale
+     *            Scale
+     */
     protected final void setScale(int scale) {
         this.scale = scale;
     }
-    
+
+    /**
+     * Gets whether the column is nullable
+     * 
+     * @return Nullability of the column
+     */
     public final int isNullable() {
         return this.nullable;
     }
-    
+
+    /**
+     * Sets the nullability of the column
+     * 
+     * @param nullable
+     *            Nullability
+     */
     protected final void setNullable(int nullable) {
         this.nullable = nullable;
     }
 
+    /**
+     * Gets whether the column is case sensitive
+     * 
+     * @return True if case sensitive, false otherwise
+     */
     public boolean isCaseSensitive() {
         // Most types in RDF/SPARQL are subject to case sensitivity especially
         // when talking strict RDF equality semantics
         return true;
     }
 
+    /**
+     * Gets whether the column represents a currency type
+     * 
+     * @return True if a currency type, false otherwise
+     */
     public boolean isCurrency() {
         // No specific currency type in RDF/SPARQL
         return false;
     }
 
+    /**
+     * Gets whether the column is an auto-increment type
+     * 
+     * @return True if auto-increment, false otherwise
+     */
     public boolean isAutoIncrement() {
         // SPARQL engines don't have a notion of auto-increment
         return false;
     }
 
+    /**
+     * Gets whether the column is writable
+     * 
+     * @return True if writable, false otherwise
+     */
     public boolean isWritable() {
         // All Jena JDBC results are read-only currently
         return false;
     }
 
+    /**
+     * Gets whether the column is read-only
+     * 
+     * @return True if read-only, false otherwise
+     */
     public boolean isReadOnly() {
         // All Jena JDBC results are read-only currently
         return true;
     }
-    
+
+    /**
+     * Gets whether the column is searchable
+     * 
+     * @return True if searchable, false otherwise
+     */
     public boolean isSearchable() {
-        // Assume all columns are searchable since the entire RDF dataset is serchable
+        // Assume all columns are searchable since the entire RDF dataset is
+        // serchable
         return true;
     }
-    
+
+    /**
+     * Gets whether the column is signed
+     * 
+     * @return True if signed, false otherwise
+     */
     public final boolean isSigned() {
         return this.signed;
     }
-    
+
+    /**
+     * Sets whether the column is signed
+     * 
+     * @param signed
+     */
     protected final void setSigned(boolean signed) {
         this.signed = signed;
     }

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DateColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DateColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DateColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DateColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Date;
+
+/**
+ * Column information for date columns
+ *
+ */
+public class DateColumn extends SparqlColumnInfo {
+
+    /**
+     * Creates new date column information
+     * @param label Label
+     * @param nullable Nullability
+     * @throws SQLException
+     */
+    public DateColumn(String label, int nullable) throws SQLException {
+        super(label, Types.DATE, nullable);
+        this.setClassName(Date.class.getCanonicalName());
+    }
+
+
+}

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DecimalColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DecimalColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DecimalColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DecimalColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.math.BigDecimal;
+import java.sql.SQLException;
+import java.sql.Types;
+
+/**
+ * Column information for decimal columns
+ *
+ */
+public class DecimalColumn extends NumericColumn {
+
+    /**
+     * Creates new decimal column information
+     * @param label Label
+     * @param nullable Nullability
+     * @throws SQLException
+     */
+    public DecimalColumn(String label, int nullable)
+            throws SQLException {
+        // Scale for xsd:decimal is 16
+        super(label, Types.DECIMAL, nullable, BigDecimal.class, 16, 16, true);
+        
+    }
+
+    
+
+}

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DoubleColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DoubleColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DoubleColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/DoubleColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+/**
+ * Column information for double columns
+ *
+ */
+public class DoubleColumn extends NumericColumn {
+    /**
+     * Creates new double column information
+     * @param label Label
+     * @param nullable Nullability
+     * @throws SQLException
+     */
+    public DoubleColumn(String label, int nullable)
+            throws SQLException {
+        super(label, Types.DOUBLE, nullable, Double.class, 16, 16, true);
+    }
+}

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/FloatColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/FloatColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/FloatColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/FloatColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+/**
+ * Column information for float columns
+ * 
+ */
+public class FloatColumn extends NumericColumn {
+
+    /**
+     * Creates new float column information
+     * 
+     * @param label
+     *            Label
+     * @param nullable
+     *            Nullability
+     * @throws SQLException
+     */
+    public FloatColumn(String label, int nullable) throws SQLException {
+        super(label, Types.FLOAT, nullable, Float.class, 7, 15, true);
+    }
+}

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/IntegerColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/IntegerColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/IntegerColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/IntegerColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+/**
+ * Column information for integer columns, integer columns report as
+ * {@link Types#BIGINT} for JDBC purposes because the XML Schema integer types
+ * equate to longs
+ * 
+ */
+public class IntegerColumn extends NumericColumn {
+
+    /**
+     * Creates new integer column information
+     * @param label Label
+     * @param nullable Nullability
+     * @param signed Whether the integer is signed
+     * @throws SQLException
+     */
+    public IntegerColumn(String label, int nullable, boolean signed) throws SQLException {
+        super(label, Types.BIGINT, nullable, Long.class, 0, Long.toString(Long.MAX_VALUE).length(), signed);
+    }
+
+}

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/NumericColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/NumericColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/NumericColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/NumericColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.sql.SQLException;
+
+/**
+ * Abstract column information for numeric columns
+ *
+ */
+public abstract class NumericColumn extends SparqlColumnInfo {
+
+    /**
+     * Creates new numeric column information
+     * @param label Column Label
+     * @param type JDBC type
+     * @param nullable Whether the column is nullable
+     * @param numericClass Numeric class
+     * @param scale Scale
+     * @param precision Precision
+     * @param signed Whether the column contains signed numbers
+     * @throws SQLException Thrown if the column information cannot be created
+     */
+    public NumericColumn(String label, int type, int nullable, Class<?> numericClass, int scale, int precision, boolean signed) throws SQLException {
+        super(label, type, nullable);
+        this.setClassName(numericClass.getCanonicalName());
+        this.setScale(scale);
+        this.setPrecision(precision);
+        this.setSigned(signed);
+    }
+
+    
+
+}

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/SparqlColumnInfo.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/SparqlColumnInfo.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/SparqlColumnInfo.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/SparqlColumnInfo.java Fri Apr  5 19:34:01 2013
@@ -18,14 +18,22 @@
 
 package org.apache.jena.jdbc.results.metadata.columns;
 
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
-import java.sql.Types;
-
 import com.hp.hpl.jena.graph.Node;
 
+/**
+ * Abstract class for column information for columns originating from SPARQL results
+ *
+ */
 public class SparqlColumnInfo extends ColumnInfo {
-    
+
+    /**
+     * Creates new column information
+     * @param label Label
+     * @param type JDBC type
+     * @param nullable Nullability
+     * @throws SQLException
+     */
     public SparqlColumnInfo(String label, int type, int nullable) throws SQLException {
         super(label, type);
         this.setClassName(Node.class.getCanonicalName());

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/StringColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/StringColumn.java?rev=1465101&r1=1465100&r2=1465101&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/StringColumn.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/StringColumn.java Fri Apr  5 19:34:01 2013
@@ -21,8 +21,18 @@ package org.apache.jena.jdbc.results.met
 import java.sql.SQLException;
 import java.sql.Types;
 
+/**
+ * Column information for string columns
+ *
+ */
 public class StringColumn extends SparqlColumnInfo {
 
+    /**
+     * Creates new string column information
+     * @param label Label
+     * @param nullable Nullability
+     * @throws SQLException
+     */
     public StringColumn(String label, int nullable) throws SQLException {
         super(label, Types.NVARCHAR, nullable);
         this.setClassName(String.class.getName());

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/TimeColumn.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/TimeColumn.java?rev=1465101&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/TimeColumn.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/columns/TimeColumn.java Fri Apr  5 19:34:01 2013
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.jdbc.results.metadata.columns;
+
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Types;
+
+/**
+ * Column information for time columns
+ * 
+ */
+public class TimeColumn extends SparqlColumnInfo {
+
+    /**
+     * Creates new time column information
+     * 
+     * @param label
+     *            Label
+     * @param nullable
+     *            Nullability
+     * @throws SQLException
+     */
+    public TimeColumn(String label, int nullable) throws SQLException {
+        super(label, Types.TIME, nullable);
+        this.setClassName(Time.class.getCanonicalName());
+    }
+
+}