ctakes-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seanfi...@apache.org
Subject svn commit: r1855612 - in /ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc: ./ db/ field/ i2b2/ row/ table/
Date Fri, 15 Mar 2019 19:08:09 GMT
Author: seanfinan
Date: Fri Mar 15 19:08:09 2019
New Revision: 1855612

URL: http://svn.apache.org/viewvc?rev=1855612&view=rev
Log:
New (Abstract) Jdbc Writing
New I2b2 Observation_Fact Jdbc Writer

Added:
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJCasJdbcWriter.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJdbcWriter.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/AbstractJdbcDb.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/JdbcDb.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/AbstractJdbcField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/BooleanField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/DoubleField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FieldFactory.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FloatField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/IntField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/JdbcField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/LongField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TextField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TimeField.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2Db.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2JdbcWriter.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactRow.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactTable.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/row/
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/row/JdbcRow.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractJdbcTable.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractUmlsTable.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/JdbcTable.java

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJCasJdbcWriter.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJCasJdbcWriter.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJCasJdbcWriter.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJCasJdbcWriter.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,44 @@
+package org.apache.ctakes.core.cc.jdbc;
+
+import org.apache.uima.jcas.JCas;
+
+
+/**
+ * Writes information pulled directly from the jcas sent to the standard process( JCas ) method.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+abstract public class AbstractJCasJdbcWriter extends AbstractJdbcWriter<JCas> {
+
+   private JCas _jCas;
+
+   /**
+    * Sets data to be written to the jcas.
+    *
+    * @param jCas ye olde
+    */
+   @Override
+   protected void createData( final JCas jCas ) {
+      _jCas = jCas;
+   }
+
+   /**
+    * @return the JCas.
+    */
+   @Override
+   protected JCas getData() {
+      return _jCas;
+   }
+
+   /**
+    * called after writing is complete
+    *
+    * @param data -
+    */
+   @Override
+   protected void writeComplete( final JCas data ) {
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJdbcWriter.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJdbcWriter.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJdbcWriter.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/AbstractJdbcWriter.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,159 @@
+package org.apache.ctakes.core.cc.jdbc;
+
+
+import org.apache.ctakes.core.cc.jdbc.db.JdbcDb;
+import org.apache.ctakes.core.cc.jdbc.table.JdbcTable;
+import org.apache.log4j.Logger;
+import org.apache.uima.UimaContext;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.fit.component.JCasAnnotator_ImplBase;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.ResourceInitializationException;
+
+import java.sql.SQLException;
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+abstract public class AbstractJdbcWriter<T> extends JCasAnnotator_ImplBase {
+
+   static private final Logger LOGGER = Logger.getLogger( "AstractJdbcWriter" );
+
+   static public final String PARAM_DB_DRIVER = "DbDriver";
+   @ConfigurationParameter(
+         name = PARAM_DB_DRIVER,
+         description = "JDBC driver ClassName."
+   )
+   private String _dbDriver;
+
+   static public final String PARAM_DB_URL = "DbUrl";
+   @ConfigurationParameter(
+         name = PARAM_DB_URL,
+         description = "JDBC URL that specifies database network location and name."
+   )
+   private String _url;
+
+   static public final String PARAM_DB_USER = "DbUser";
+   @ConfigurationParameter(
+         name = PARAM_DB_USER,
+         description = "Username for database authentication."
+   )
+   private String _user;
+
+   static public final String PARAM_DB_PASS = "DbPass";
+   @ConfigurationParameter(
+         name = PARAM_DB_PASS,
+         description = "Password for database authentication."
+   )
+   private String _pass;
+
+   static public final String PARAM_KEEP_ALIVE = "KeepAlive";
+   @ConfigurationParameter(
+         name = PARAM_KEEP_ALIVE,
+         description = "Flag that determines whether to keep JDBC connection open no matter what.",
+         mandatory = false
+   )
+   private String _keepAlive;
+
+
+   // Maximum row count for prepared statement batches
+   static private final int MAX_BATCH_SIZE = 100;
+
+   static private final Object DATA_LOCK = new Object();
+
+
+   private JdbcDb _jdbcDb;
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void initialize( final UimaContext context ) throws ResourceInitializationException {
+      super.initialize( context );
+      _jdbcDb = createJdbcDb( _dbDriver, _url, _user, _pass, _keepAlive );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void process( final JCas jcas ) throws AnalysisEngineProcessException {
+      try {
+         synchronized ( DATA_LOCK ) {
+            createData( jcas );
+            final T data = getData();
+            if ( data != null ) {
+               writeJdbc( data );
+               writeComplete( data );
+            }
+         }
+      } catch ( SQLException sqlE ) {
+         throw new AnalysisEngineProcessException( sqlE );
+      }
+   }
+
+   /**
+    * Write any remaining patient information
+    * {@inheritDoc}
+    */
+   @Override
+   public void collectionProcessComplete() throws AnalysisEngineProcessException {
+      super.collectionProcessComplete();
+      try {
+         _jdbcDb.close();
+      } catch ( SQLException sqlE ) {
+         LOGGER.error( sqlE.getMessage() );
+      }
+   }
+
+   abstract protected JdbcDb createJdbcDb( final String driver,
+                                           final String url,
+                                           final String user,
+                                           final String pass,
+                                           final String keepAlive ) throws ResourceInitializationException;
+
+   /**
+    * @param jCas the jcas passed to the process( jcas ) method.
+    */
+   abstract protected void createData( JCas jCas );
+
+   /**
+    * @return the data to be written.
+    */
+   abstract protected T getData();
+
+   /**
+    * called after writing is complete
+    *
+    * @param data -
+    */
+   abstract protected void writeComplete( T data );
+
+   /**
+    * Write information into a table.
+    *
+    * @param data data to be written.
+    * @throws SQLException if anything goes wrong.
+    */
+   public void writeJdbc( final T data ) throws SQLException {
+      for ( JdbcTable<T> table : getJdbcTables( (Class<T>)data.getClass() ) ) {
+         table.writeValue( data );
+      }
+   }
+
+   /**
+    * The JdbcDb used by this writer can have multiple tables for various datatypes.
+    *
+    * @param dataClass class of data for this writer.
+    * @return tables in database that can use this data class.
+    */
+   private Collection<JdbcTable<T>> getJdbcTables( final Class<T> dataClass ) {
+      return _jdbcDb.getTables( dataClass );
+   }
+
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/AbstractJdbcDb.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/AbstractJdbcDb.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/AbstractJdbcDb.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/AbstractJdbcDb.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,72 @@
+package org.apache.ctakes.core.cc.jdbc.db;
+
+
+import org.apache.ctakes.core.cc.jdbc.table.JdbcTable;
+import org.apache.uima.resource.ResourceInitializationException;
+import sqlWrapper.WrappedConnection;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+abstract public class AbstractJdbcDb implements JdbcDb {
+
+   private final Connection _connection;
+
+   private final Collection<JdbcTable<?>> _jdbcTables = new ArrayList<>();
+
+   public AbstractJdbcDb( final String driver,
+                          final String url,
+                          final String user,
+                          final String pass,
+                          final String keepAlive ) throws ResourceInitializationException {
+      _connection = createConnection( driver, url, user, pass, keepAlive );
+   }
+
+   /**
+    * @param driver    -
+    * @param url       -
+    * @param user      -
+    * @param pass      -
+    * @param keepAlive -
+    * @return a connection to the database
+    * @throws ResourceInitializationException -
+    */
+   static private Connection createConnection( final String driver,
+                                               final String url,
+                                               final String user,
+                                               final String pass,
+                                               final String keepAlive ) throws ResourceInitializationException {
+      final Object[] emptyObjectArray = new Object[ 0 ];
+      try {
+         if ( keepAlive != null && !keepAlive.isEmpty() && Boolean.valueOf( keepAlive ) ) {
+            return new WrappedConnection( user, pass, driver, url );
+         }
+         final Class driverClass = Class.forName( driver );
+         return DriverManager.getConnection( url, user, pass );
+      } catch ( ClassNotFoundException | SQLException multE ) {
+         throw new ResourceInitializationException( "Could not construct " + driver,
+               emptyObjectArray, multE );
+      }
+   }
+
+   public Connection getConnection() {
+      return _connection;
+   }
+
+   final public void addTable( final JdbcTable<?> table ) {
+      _jdbcTables.add( table );
+   }
+
+   final public Collection<JdbcTable<?>> getTables() {
+      return _jdbcTables;
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/JdbcDb.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/JdbcDb.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/JdbcDb.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/db/JdbcDb.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,52 @@
+package org.apache.ctakes.core.cc.jdbc.db;
+
+
+import org.apache.ctakes.core.cc.jdbc.table.JdbcTable;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+public interface JdbcDb {
+
+   /**
+    * @param table new table to register.
+    */
+   void addTable( final JdbcTable<?> table );
+
+   /**
+    * @return all registered tables.
+    */
+   Collection<JdbcTable<?>> getTables();
+
+   /**
+    * @param dataClass class of data.
+    * @return all registered tables that handle that type of data.
+    */
+   default <T> Collection<JdbcTable<T>> getTables( final Class<T> dataClass ) {
+      final Collection<JdbcTable<T>> tables = new ArrayList<>();
+      for ( JdbcTable<?> table : getTables() ) {
+         if ( table.getDataType().equals( dataClass ) ) {
+            tables.add( (JdbcTable<T>)table );
+         }
+      }
+      return tables;
+   }
+
+   /**
+    * Close each table.
+    *
+    * @throws SQLException -
+    */
+   default void close() throws SQLException {
+      for ( JdbcTable<?> table : getTables() ) {
+         table.close();
+      }
+   }
+
+}
\ No newline at end of file

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/AbstractJdbcField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/AbstractJdbcField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/AbstractJdbcField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/AbstractJdbcField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,35 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+abstract public class AbstractJdbcField<FT> implements JdbcField<FT> {
+
+   private final String _name;
+   private final int _index;
+
+   public AbstractJdbcField( final String name, final int index ) {
+      _name = name;
+      _index = index;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getFieldName() {
+      return _name;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getFieldIndex() {
+      return _index;
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/BooleanField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/BooleanField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/BooleanField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/BooleanField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,22 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class BooleanField extends AbstractJdbcField<Boolean> {
+
+   public BooleanField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final Boolean value ) throws SQLException {
+      statement.setBoolean( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/DoubleField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/DoubleField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/DoubleField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/DoubleField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,22 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class DoubleField extends AbstractJdbcField<Double> {
+
+   public DoubleField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final Double value ) throws SQLException {
+      statement.setDouble( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FieldFactory.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FieldFactory.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FieldFactory.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FieldFactory.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,49 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class FieldFactory {
+
+   static private final Logger LOGGER = Logger.getLogger( "FieldFactory" );
+
+   private FieldFactory() {
+   }
+
+   static public JdbcField createField( final String type, final String name ) {
+      switch ( type.toLowerCase().trim() ) {
+         case "string":
+            return new TextField( name );
+         case "text":
+            return new TextField( name );
+         case "int":
+            return new IntField( name );
+         case "integer":
+            return new IntField( name );
+         case "long":
+            return new LongField( name );
+         case "number":
+            return new LongField( name );
+         case "float":
+            return new FloatField( name );
+         case "double":
+            return new DoubleField( name );
+         case "decimal":
+            return new DoubleField( name );
+         case "timestamp":
+            return new TimeField( name );
+         case "time":
+            return new TimeField( name );
+         case "date":
+            return new TimeField( name );
+      }
+      throw new IllegalArgumentException( "Unknown Field Type : " + type );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FloatField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FloatField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FloatField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/FloatField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,22 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class FloatField extends AbstractJdbcField<Float> {
+
+   public FloatField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final Float value ) throws SQLException {
+      statement.setFloat( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/IntField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/IntField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/IntField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/IntField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,22 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class IntField extends AbstractJdbcField<Integer> {
+
+   public IntField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final Integer value ) throws SQLException {
+      statement.setInt( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/JdbcField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/JdbcField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/JdbcField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/JdbcField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,23 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+public interface JdbcField<T> {
+
+   int NO_INDEX = -1;
+
+   String getFieldName();
+
+   default int getFieldIndex() {
+      return NO_INDEX;
+   }
+
+   void addToStatement( final CallableStatement statement, final T value ) throws SQLException;
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/LongField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/LongField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/LongField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/LongField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,22 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class LongField extends AbstractJdbcField<Long> {
+
+   public LongField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final Long value ) throws SQLException {
+      statement.setLong( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TextField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TextField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TextField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TextField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,22 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class TextField extends AbstractJdbcField<String> {
+
+   public TextField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final String value ) throws SQLException {
+      statement.setString( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TimeField.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TimeField.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TimeField.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/field/TimeField.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,23 @@
+package org.apache.ctakes.core.cc.jdbc.field;
+
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class TimeField extends AbstractJdbcField<Timestamp> {
+
+   public TimeField( final String name ) {
+      super( name, NO_INDEX );
+   }
+
+   public void addToStatement( final CallableStatement statement, final Timestamp value ) throws SQLException {
+      statement.setTimestamp( getFieldName(), value );
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2Db.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2Db.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2Db.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2Db.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,50 @@
+package org.apache.ctakes.core.cc.jdbc.i2b2;
+
+import org.apache.ctakes.core.cc.jdbc.db.AbstractJdbcDb;
+import org.apache.uima.resource.ResourceInitializationException;
+
+import java.sql.SQLException;
+
+import static org.apache.ctakes.core.cc.jdbc.i2b2.ObservationFactTable.CorpusSettings;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/15/2019
+ */
+public class I2b2Db extends AbstractJdbcDb {
+
+
+   public I2b2Db( final String driver,
+                  final String url,
+                  final String user,
+                  final String pass,
+                  final String keepAlive ) throws ResourceInitializationException {
+      super( driver, url, user, pass, keepAlive );
+   }
+
+   /**
+    * @param tableName name of the output observation fact table.
+    * @return observation fact table with only negation marked by a negative (-) sign before concept codes.
+    * @throws SQLException -
+    */
+   protected ObservationFactTable addObservationFact( final String tableName ) throws SQLException {
+      final CorpusSettings settings = new CorpusSettings( CorpusSettings.Marker.MARK_NEGATED );
+      return addObservationFact( tableName, settings );
+   }
+
+   /**
+    * @param tableName      name of the output observation fact table.
+    * @param corpusSettings settings for marking negation, uncertainty and generics.
+    * @return observation fact table.
+    * @throws SQLException -
+    */
+   protected ObservationFactTable addObservationFact( final String tableName,
+                                                      final CorpusSettings corpusSettings ) throws SQLException {
+      final ObservationFactTable table = new ObservationFactTable( getConnection(), tableName, corpusSettings );
+      addTable( table );
+      return table;
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2JdbcWriter.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2JdbcWriter.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2JdbcWriter.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/I2b2JdbcWriter.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,41 @@
+package org.apache.ctakes.core.cc.jdbc.i2b2;
+
+import org.apache.ctakes.core.cc.jdbc.AbstractJCasJdbcWriter;
+import org.apache.ctakes.core.cc.jdbc.db.JdbcDb;
+import org.apache.uima.fit.descriptor.ConfigurationParameter;
+import org.apache.uima.resource.ResourceInitializationException;
+
+import java.sql.SQLException;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+public class I2b2JdbcWriter extends AbstractJCasJdbcWriter {
+
+
+   static public final String PARAM_TABLE_NAME = "FactOutputTable";
+   @ConfigurationParameter(
+         name = PARAM_TABLE_NAME,
+         description = "Name of the Observation_Fact table for writing output."
+   )
+   private String _tableName;
+
+
+   final protected JdbcDb createJdbcDb( final String driver,
+                                        final String url,
+                                        final String user,
+                                        final String pass,
+                                        final String keepAlive ) throws ResourceInitializationException {
+      final I2b2Db db = new I2b2Db( driver, url, user, pass, keepAlive );
+      try {
+         db.addObservationFact( _tableName );
+      } catch ( SQLException sqlE ) {
+         throw new ResourceInitializationException( sqlE );
+      }
+      return db;
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactRow.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactRow.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactRow.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactRow.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,210 @@
+package org.apache.ctakes.core.cc.jdbc.i2b2;
+
+import org.apache.ctakes.core.cc.jdbc.field.IntField;
+import org.apache.ctakes.core.cc.jdbc.field.LongField;
+import org.apache.ctakes.core.cc.jdbc.field.TextField;
+import org.apache.ctakes.core.cc.jdbc.field.TimeField;
+import org.apache.ctakes.core.cc.jdbc.row.JdbcRow;
+import org.apache.ctakes.core.util.SourceMetadataUtil;
+import org.apache.ctakes.typesystem.type.constants.CONST;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.ctakes.typesystem.type.structured.SourceData;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.ResourceProcessException;
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.apache.ctakes.core.cc.jdbc.i2b2.ObservationFactTable.CorpusSettings;
+
+/**
+ * For the format of the I2B2 Observation_Fact table,
+ * see https://www.i2b2.org/software/projects/datarepo/CRC_Design_Doc_13.pdf
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/14/2019
+ */
+final public class ObservationFactRow
+      implements JdbcRow<CorpusSettings, JCas, JCas, IdentifiedAnnotation, UmlsConcept> {
+
+   static private final Logger LOGGER = Logger.getLogger( "ObservationFactRow" );
+
+   static private final String PATIENT_NUM = "patient_num";
+   static private final String PROVIDER_ID = "provider_id";
+   static private final String ENCOUNTER_NUM = "encounter_num";
+   static private final String START_DATE = "start_date";
+   static private final String INSTANCE_NUM = "instance_num";
+   static private final String CONCEPT_CD = "concept_cd";
+   static private final String MODIFIER_CD = "modifier_cd";
+   static private final String VALTYPE_CD = "valtype_cd";
+   static private final String TVAL_CHAR = "tval_char";
+   static private final String OBSERVATION_BLOB = "observation_blob";
+
+   static private final String DEFAULT_MODIFIER_CD = "@";
+   static private final String DEFAULT_VALTYPE_CD = "T";
+
+   static private final String NEGATED_MARK = "-";
+   static private final String UNCERTAIN_MARK = "~";
+   static private final String GENERIC_MARK = "*";
+   static private final String NO_MARK = "";
+
+
+   // Per Patient
+   private final LongField _patientNum = new LongField( PATIENT_NUM );
+
+   // Per Document
+   private final TextField _providerId = new TextField( PROVIDER_ID );
+   private final IntField _encounterNum = new IntField( ENCOUNTER_NUM );
+   private final TimeField _startDate = new TimeField( START_DATE );
+
+   // Per Row
+   private final LongField _instanceNum = new LongField( INSTANCE_NUM );
+   private final TextField _conceptCd = new TextField( CONCEPT_CD );
+   private final TextField _modifierCd = new TextField( MODIFIER_CD );
+   private final TextField _valtypeCd = new TextField( VALTYPE_CD );
+   private final TextField _tvalChar = new TextField( TVAL_CHAR );
+   private final TextField _observationBlob = new TextField( OBSERVATION_BLOB );
+
+   // Per Patient
+   private long _patient;
+
+   // Per Document
+   private String _provider;
+   private int _encounter;
+   private Timestamp _start;
+   private long _instance;
+
+   // Per Row
+   private String _negatedMark;
+   private String _uncertainMark;
+   private String _genericMark;
+
+   private String _conceptPrefix;
+   private IdentifiedAnnotation _annotation;
+
+
+   public Collection<String> getFieldNames() {
+      return Arrays.asList( PATIENT_NUM,
+            // Per Document
+            PROVIDER_ID, ENCOUNTER_NUM, START_DATE,
+            // Per Row
+            INSTANCE_NUM, CONCEPT_CD, MODIFIER_CD, VALTYPE_CD, TVAL_CHAR, OBSERVATION_BLOB );
+   }
+
+   public void initializeCorpus( final CorpusSettings corpusValue ) {
+      _negatedMark = corpusValue.markNegated() ? NEGATED_MARK : NO_MARK;
+      _uncertainMark = corpusValue.markUncertain() ? UNCERTAIN_MARK : NO_MARK;
+      _genericMark = corpusValue.markGeneric() ? GENERIC_MARK : NO_MARK;
+   }
+
+   /**
+    * {@inheritDoc}
+    * <p>
+    * Sets the patient_num.
+    */
+   @Override
+   public void initializePatient( final JCas patientValue ) {
+      _patient = SourceMetadataUtil.getPatientNum( patientValue );
+   }
+
+   /**
+    * {@inheritDoc}
+    * <p>
+    * Set the encounter_num, provider_id, start_date.
+    */
+   @Override
+   public void initializeDocument( final JCas documentValue ) {
+      _instance = 1;
+      final SourceData sourceData = SourceMetadataUtil.getSourceData( documentValue );
+      if ( sourceData == null ) {
+         LOGGER.warn( "No document source data." );
+         setEmptyDocInfo();
+         return;
+      }
+      try {
+         _encounter = SourceMetadataUtil.getEncounterNum( sourceData );
+         _provider = SourceMetadataUtil.getProviderId( sourceData );
+         _start = SourceMetadataUtil.getStartDate( sourceData );
+      } catch ( ResourceProcessException rpE ) {
+         LOGGER.warn( "Error setting document source data: " + rpE.getMessage() );
+         setEmptyDocInfo();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    * <p>
+    * Set the encounter_num, provider_id, start_date.
+    */
+   public void initializeEntity( final IdentifiedAnnotation entityValue ) {
+      _annotation = entityValue;
+      _conceptPrefix = ""
+                       + (_annotation.getPolarity() == CONST.NE_POLARITY_NEGATION_PRESENT ? _negatedMark : NO_MARK)
+                       + (_annotation.getUncertainty() == CONST.NE_UNCERTAINTY_PRESENT ? _uncertainMark : NO_MARK)
+                       + (_annotation.getGeneric() ? _genericMark : NO_MARK);
+   }
+
+   /**
+    * {@inheritDoc}
+    * <p>
+    * Set the concept_cd, modifier_cd, instance_num, valtype_cd, tval_char, observation_blob.
+    */
+   @Override
+   public void addToStatement( final CallableStatement statement,
+                               final UmlsConcept value ) throws SQLException {
+      // Per Patient
+      _patientNum.addToStatement( statement, _patient );
+
+      // Per Document
+      _providerId.addToStatement( statement, _provider );
+      _encounterNum.addToStatement( statement, _encounter );
+      _startDate.addToStatement( statement, _start );
+
+      // Per Row
+      _instanceNum.addToStatement( statement, _instance );
+      _conceptCd.addToStatement( statement, getConceptCode( value ) );
+      _modifierCd.addToStatement( statement, getModifierCd( value ) );
+      _valtypeCd.addToStatement( statement, getValtypeCd( value ) );
+      _tvalChar.addToStatement( statement, getTvalChar( value ) );
+      _observationBlob.addToStatement( statement, getObservationBlob( value ) );
+
+      _instance++;
+   }
+
+   /**
+    * Set document information as empty.
+    */
+   private void setEmptyDocInfo() {
+      _encounter = -1;
+      _provider = "";
+      _start = Timestamp.valueOf( "" );
+   }
+
+   private String getConceptCode( final UmlsConcept concept ) {
+      return _conceptPrefix + concept.getCui();
+   }
+
+   private String getModifierCd( final UmlsConcept concept ) {
+      return DEFAULT_MODIFIER_CD;
+   }
+
+   private String getValtypeCd( final UmlsConcept concept ) {
+      return DEFAULT_VALTYPE_CD;
+   }
+
+   private String getTvalChar( final UmlsConcept concept ) {
+      return concept.getPreferredText();
+   }
+
+   private String getObservationBlob( final UmlsConcept concept ) {
+      return "";
+   }
+
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactTable.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactTable.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactTable.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/i2b2/ObservationFactTable.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,81 @@
+package org.apache.ctakes.core.cc.jdbc.i2b2;
+
+
+import org.apache.ctakes.core.cc.jdbc.row.JdbcRow;
+import org.apache.ctakes.core.cc.jdbc.table.AbstractUmlsTable;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.apache.ctakes.core.cc.jdbc.i2b2.ObservationFactTable.CorpusSettings;
+
+
+/**
+ * For the format of the I2B2 Observation_Fact table,
+ * see https://www.i2b2.org/software/projects/datarepo/CRC_Design_Doc_13.pdf
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+final public class ObservationFactTable extends AbstractUmlsTable<CorpusSettings> {
+
+   static private final Logger LOGGER = Logger.getLogger( "I2B2JdbcTable" );
+
+   private final CorpusSettings _corpusSettings;
+
+   public ObservationFactTable( final Connection connection,
+                                final String tableName,
+                                final CorpusSettings corpusSettings ) throws SQLException {
+      super( connection, tableName );
+      _corpusSettings = corpusSettings;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected CorpusSettings getCorpusInitializer( final JCas jCas ) {
+      return _corpusSettings;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public JdbcRow<CorpusSettings, JCas, JCas, IdentifiedAnnotation, UmlsConcept> createJdbcRow() {
+      return new ObservationFactRow();
+   }
+
+
+   static public class CorpusSettings {
+      public enum Marker {
+         MARK_NEGATED, MARK_UNCERTAIN, MARK_GENERIC;
+      }
+
+      final Collection<Marker> _markers;
+
+      public CorpusSettings( final Marker... markers ) {
+         _markers = Arrays.asList( markers );
+      }
+
+      boolean markNegated() {
+         return _markers.contains( Marker.MARK_NEGATED );
+      }
+
+      boolean markUncertain() {
+         return _markers.contains( Marker.MARK_UNCERTAIN );
+      }
+
+      boolean markGeneric() {
+         return _markers.contains( Marker.MARK_GENERIC );
+      }
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/row/JdbcRow.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/row/JdbcRow.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/row/JdbcRow.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/row/JdbcRow.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,30 @@
+package org.apache.ctakes.core.cc.jdbc.row;
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/14/2019
+ */
+public interface JdbcRow<C, P, D, E, T> {
+
+   Collection<String> getFieldNames();
+
+   default void initializeCorpus( final C corpusValue ) {
+   }
+
+   default void initializePatient( final P patientValue ) {
+   }
+
+   default void initializeDocument( final D documentValue ) {
+   }
+
+   default void initializeEntity( final E entityValue ) {
+   }
+
+   void addToStatement( final CallableStatement statement, final T value ) throws SQLException;
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractJdbcTable.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractJdbcTable.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractJdbcTable.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractJdbcTable.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,76 @@
+package org.apache.ctakes.core.cc.jdbc.table;
+
+
+import javax.annotation.concurrent.NotThreadSafe;
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+@NotThreadSafe
+abstract public class AbstractJdbcTable<T> implements JdbcTable<T> {
+
+   static private final int DEFAULT_BATCH_LIMIT = 100;
+
+   private final String _tableName;
+   private final CallableStatement _callableStatement;
+   private int _batchLimit = DEFAULT_BATCH_LIMIT;
+   private int _batchIndex = 0;
+
+   public AbstractJdbcTable( final Connection connection, final String tableName ) throws SQLException {
+      _tableName = tableName;
+      final String sql = createRowInsertSql();
+      _callableStatement = connection.prepareCall( sql );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public String getTableName() {
+      return _tableName;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public CallableStatement getCallableStatement() {
+      return _callableStatement;
+   }
+
+   /**
+    * @param limit batch size limit after which the batch is written to the db table.  Max 10,000.
+    */
+   final public void setBatchLimit( final int limit ) {
+      if ( limit > 0 && limit <= 10000 ) {
+         _batchLimit = limit;
+      }
+   }
+
+   /**
+    * @return batch size limit after which the batch is written to the db table.
+    */
+   final public int getBatchLimit() {
+      return _batchLimit;
+   }
+
+   /**
+    * @return true if the statement batch was written.
+    * @throws SQLException -
+    */
+   protected boolean incrementBatchIndex() throws SQLException {
+      _batchIndex++;
+      if ( _batchIndex >= DEFAULT_BATCH_LIMIT ) {
+         _batchIndex = 0;
+         getCallableStatement().executeBatch();
+         return true;
+      }
+      return false;
+   }
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractUmlsTable.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractUmlsTable.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractUmlsTable.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/AbstractUmlsTable.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,85 @@
+package org.apache.ctakes.core.cc.jdbc.table;
+
+
+import org.apache.ctakes.core.cc.jdbc.row.JdbcRow;
+import org.apache.ctakes.core.util.OntologyConceptUtil;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.uima.fit.util.JCasUtil;
+import org.apache.uima.jcas.JCas;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+
+/**
+ * Table that has one row per UmlsConcept in the JCas.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/14/2019
+ */
+abstract public class AbstractUmlsTable<C> extends AbstractJdbcTable<JCas> {
+
+   private JdbcRow<C, JCas, JCas, IdentifiedAnnotation, UmlsConcept> _jdbcRow;
+
+   public AbstractUmlsTable( final Connection connection, final String tableName ) throws SQLException {
+      super( connection, tableName );
+   }
+
+   /**
+    * @param jCas ye olde ...
+    * @return some class that can be used to initialize the table.
+    */
+   abstract protected C getCorpusInitializer( final JCas jCas );
+
+   /**
+    * @return some row that uses JCas, Identified annotation, and a UmlsConcept per row.
+    */
+   abstract protected JdbcRow<C, JCas, JCas, IdentifiedAnnotation, UmlsConcept> createJdbcRow();
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public Class<JCas> getDataType() {
+      return JCas.class;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public JdbcRow<C, JCas, JCas, IdentifiedAnnotation, UmlsConcept> getJdbcRow() {
+      if ( _jdbcRow == null ) {
+         _jdbcRow = createJdbcRow();
+      }
+      return _jdbcRow;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public void writeValue( final JCas value ) throws SQLException {
+      final CallableStatement statement = getCallableStatement();
+      final C corpusInitializer = getCorpusInitializer( value );
+      final JdbcRow<C, JCas, JCas, IdentifiedAnnotation, UmlsConcept> row = getJdbcRow();
+
+      row.initializeCorpus( corpusInitializer );
+      row.initializePatient( value );
+      row.initializeDocument( value );
+      final Collection<IdentifiedAnnotation> annotations = JCasUtil.select( value, IdentifiedAnnotation.class );
+      for ( IdentifiedAnnotation annotation : annotations ) {
+         row.initializeEntity( annotation );
+         final Collection<UmlsConcept> umlsConcepts = OntologyConceptUtil.getUmlsConcepts( annotation );
+         for ( UmlsConcept concept : umlsConcepts ) {
+            row.addToStatement( statement, concept );
+            incrementBatchIndex();
+         }
+      }
+   }
+
+
+}

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/JdbcTable.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/JdbcTable.java?rev=1855612&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/JdbcTable.java (added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cc/jdbc/table/JdbcTable.java Fri Mar 15 19:08:09 2019
@@ -0,0 +1,59 @@
+package org.apache.ctakes.core.cc.jdbc.table;
+
+
+import org.apache.ctakes.core.cc.jdbc.row.JdbcRow;
+
+import java.sql.CallableStatement;
+import java.sql.SQLDataException;
+import java.sql.SQLException;
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 3/12/2019
+ */
+public interface JdbcTable<T> {
+
+   String getTableName();
+
+   Class<T> getDataType();
+
+   JdbcRow<?, ?, ?, ?, ?> getJdbcRow();
+
+   CallableStatement getCallableStatement();
+
+   default Collection<String> getFieldNames() {
+      return getJdbcRow().getFieldNames();
+   }
+
+   void writeValue( final T value ) throws SQLException;
+
+   /**
+    * @return -
+    * @throws SQLDataException -
+    */
+   default String createRowInsertSql() throws SQLDataException {
+      if ( getFieldNames().isEmpty() ) {
+         throw new SQLDataException( "Must set at least one Field to create an sql insert Statement" );
+      }
+      final StringBuilder statement = new StringBuilder( "insert into" );
+      final StringBuilder queries = new StringBuilder();
+      statement.append( " " ).append( getTableName() );
+      statement.append( " (" );
+      for ( String fieldName : getFieldNames() ) {
+         statement.append( fieldName ).append( "," );
+         queries.append( "?," );
+      }
+      // remove the last comma
+      statement.setLength( statement.length() - 1 );
+      queries.setLength( queries.length() - 1 );
+      statement.append( ") values (" ).append( queries ).append( ")" );
+      return statement.toString();
+   }
+
+   default void close() throws SQLException {
+      getCallableStatement().close();
+   }
+
+}



Mime
View raw message