Commit ff135840 authored by R.W.Majeed's avatar R.W.Majeed

database testing with embedded hsql database.

junit tests for visit and patient store
parent 33858763
......@@ -17,11 +17,6 @@
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
......@@ -33,5 +28,17 @@
<artifactId>histream-core</artifactId>
<version>0.16-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -73,6 +73,8 @@ public class I2b2Visit extends VisitImpl {
// also set the patient_num
int patient_num = ((I2b2Patient)patient).getNum();
this.patient_num = patient_num;
}else {
throw new IllegalArgumentException("Patient expected of instanceOf I2b2Patient");
}
}
......
......@@ -43,6 +43,7 @@ import java.util.logging.Logger;
import de.sekmi.histream.DateTimeAccuracy;
import de.sekmi.histream.Observation;
import de.sekmi.histream.ext.ExternalSourceType;
import de.sekmi.histream.ext.Patient;
import de.sekmi.histream.ext.StoredExtensionType;
import de.sekmi.histream.ext.Visit;
import de.sekmi.histream.ext.Visit.Status;
......@@ -476,6 +477,9 @@ public class PostgresVisitStore extends PostgresExtension<I2b2Visit> implements
return getOrCreateInstance(fact.getEncounterId(), fact.getExtension(I2b2Patient.class), fact.getSource());
}
public I2b2Visit createInstance(String encounterId, Patient patient, ExternalSourceType source) {
return getOrCreateInstance(encounterId, (I2b2Patient)patient, source);
}
@Override
public Iterable<Class<? super I2b2Visit>> getInstanceTypes() {
return INSTANCE_TYPES;
......
package de.sekmi.histream.i2b2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
import java.util.logging.Logger;
import javax.sql.DataSource;
// TODO move to query-i2b2-sql
public class LocalHSQLDataSource implements DataSource{
private PrintWriter pw;
private static final String JDBC_URI = "jdbc:hsqldb:file:target/testdb_crcdata";
public void delete() throws SQLException {
try( Connection c = getConnection() ){
Statement s = c.createStatement();
s = c.createStatement();
s.executeQuery("DROP SCHEMA PUBLIC CASCADE");
s.close();
}
}
private static void executeSQL(Connection dbc, BufferedReader lines) throws SQLException, IOException {
StringBuilder stmt = new StringBuilder();
String line;
while( (line = lines.readLine()) != null ) {
line = line.trim();
if( line.trim().startsWith("--") ) {
// ignore comment lines
continue;
}
if( line.endsWith(";") ) {
// append without ;
stmt.append(line.substring(0, line.length()-1));
// execute
try( Statement s = dbc.createStatement() ){
s.executeUpdate(stmt.toString());
}
// clear
stmt = new StringBuilder();
}else {
stmt.append(line);
}
}
}
/**
* Create the database and initialize it with the specified DDL statements
* @param sql_ddl SQL DDL statements
* @throws SQLException SQL error
* @throws IOException IO error reading the DDL
*/
public void create(BufferedReader ... sql_ddl) throws SQLException, IOException {
try( Connection dbc = DriverManager.getConnection(JDBC_URI+";create=true", "SA", "") ){
for( BufferedReader ddl : sql_ddl ) {
executeSQL(dbc, ddl);
}
}
}
public void createI2b2() throws SQLException, IOException {
try( InputStream in = TestHSQLDataSource.class.getResourceAsStream("/i2b2_hsqldb_ddl_create.sql");
BufferedReader rd = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)) )
{
this.create(rd);
}
}
public Integer executeCountQuery(String sql) throws SQLException {
Integer ret = null;
try( Connection c = getConnection();
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(sql) )
{
if( rs.next() ) {
ret = rs.getInt(1);
}
}
return ret;
}
public LocalHSQLDataSource() {
pw = new PrintWriter(System.out);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return pw;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
this.pw = out;
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new UnsupportedOperationException();
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
throw new UnsupportedOperationException();
}
@Override
public Connection getConnection() throws SQLException {
return getConnection("SA","");
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return DriverManager.getConnection(JDBC_URI+";ifexists=true", username, password);
}
}
package de.sekmi.histream.i2b2;
import java.io.IOException;
import java.sql.SQLException;
import org.junit.Assert;
import org.junit.Test;
public class TestHSQLDataSource {
@Test
public void testCreateTables() throws IOException, SQLException {
LocalHSQLDataSource ds = new LocalHSQLDataSource();
ds.createI2b2();
// perform queries
Assert.assertEquals(0, ds.executeCountQuery("SELECT COUNT(*) FROM observation_fact").intValue());
// drop database
ds.delete();
}
}
......@@ -25,11 +25,54 @@ import java.io.Closeable;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.time.Instant;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import de.sekmi.histream.ext.ExternalSourceType;
import de.sekmi.histream.i2b2.PostgresPatientStore;
import de.sekmi.histream.impl.ExternalSourceImpl;
public class TestPostgresPatientStore implements Closeable {
PostgresPatientStore store;
LocalHSQLDataSource ds;
@Before
public void createDatabase() throws SQLException, IOException {
ds = new LocalHSQLDataSource();
ds.delete();
ds.createI2b2();
}
private void openPatientStore() throws SQLException {
store = new PostgresPatientStore();
store.open(ds.getConnection(), "test", new DataDialect());
}
@After
public void cleanupDatabase() throws SQLException, IOException {
if( store != null ) {
store.close();
}
ds.delete();
}
@Test
public void insertPatient() throws IOException, SQLException {
ExternalSourceType t = new ExternalSourceImpl("junit", Instant.now());
openPatientStore();
store.createInstance("ABC001", t);
store.flush();
store.close();
store = null;
// reload store from database
openPatientStore();
// attempt to load previously stored patient
I2b2Patient p = store.retrieve("ABC001");
Assert.assertNotNull(p);
}
public void open(String host, int port, String user, String password, String projectId) throws ClassNotFoundException, SQLException{
store = new PostgresPatientStore();
store.open(DriverManager.getConnection("jdbc:postgresql://"+host+":"+port+"/i2b2", user, password),projectId, new DataDialect());
......
......@@ -25,15 +25,76 @@ import java.io.Closeable;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.time.Instant;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import de.sekmi.histream.DateTimeAccuracy;
import de.sekmi.histream.ext.ExternalSourceType;
import de.sekmi.histream.i2b2.PostgresVisitStore;
import de.sekmi.histream.impl.ExternalSourceImpl;
public class TestPostgresVisitStore implements Closeable {
private PostgresVisitStore store;
private PostgresVisitStore vs;
private PostgresPatientStore ps;
LocalHSQLDataSource ds;
@Before
public void createDatabase() throws SQLException, IOException {
ds = new LocalHSQLDataSource();
ds.delete();
ds.createI2b2();
}
private void openVisitStore() throws SQLException {
ps = new PostgresPatientStore();
ps.open(ds.getConnection(), "test", new DataDialect());
vs = new PostgresVisitStore();
vs.open(ds.getConnection(), "test", new DataDialect());
}
@After
public void cleanupDatabase() throws SQLException, IOException {
if( vs != null ) {
vs.close();
}
if( ps != null ) {
ps.close();
}
ds.delete();
}
@Test
public void insertVisit() throws IOException, SQLException {
ExternalSourceType t = new ExternalSourceImpl("junit", Instant.now());
openVisitStore();
// create patient
I2b2Patient pat = ps.createInstance("ABC001", t);
I2b2Visit v = vs.createInstance("VIS001", pat, t);
v.setStartTime(new DateTimeAccuracy(Instant.now()));
v = vs.findVisit("VIS001");
Assert.assertEquals("ABC001",v.getPatientId());
// TODO reload store from database
vs.close();
vs = null;
ps.close();
ps = null;
// attempt to load previously stored patient
openVisitStore();
v = vs.findVisit("VIS001");
Assert.assertNotNull(v);
Assert.assertEquals("ABC001",v.getPatientId());
}
public void open(String host, int port) throws ClassNotFoundException, SQLException{
store = new PostgresVisitStore();
store.open(DriverManager.getConnection("jdbc:postgresql://"+host+":"+port+"/i2b2", "i2b2demodata", "demodata"), "demo", new DataDialect());
vs = new PostgresVisitStore();
vs.open(DriverManager.getConnection("jdbc:postgresql://"+host+":"+port+"/i2b2", "i2b2demodata", "demodata"), "demo", new DataDialect());
}
private void open()throws Exception{
......@@ -42,15 +103,15 @@ public class TestPostgresVisitStore implements Closeable {
@Override
public void close() throws IOException{
store.close();
vs.close();
}
public PostgresVisitStore getStore(){ return store; }
public PostgresVisitStore getStore(){ return vs; }
public static void main(String args[]) throws Exception{
TestPostgresVisitStore t = new TestPostgresVisitStore();
t.open();
System.out.println("Current visit cache size: "+t.store.size());
System.out.println("Current visit cache size: "+t.vs.size());
t.close();
}
}
-- demo data for testing query executions via SQL
INSERT INTO patient_dimension(patient_num,vital_status_cd,birth_date,sex_cd)VALUES(1001, NULL, '2001-01-01','F');
INSERT INTO patient_dimension(patient_num,vital_status_cd,birth_date,sex_cd)VALUES(1002, NULL, '2002-02-02','M');
INSERT INTO patient_dimension(patient_num,vital_status_cd,birth_date,sex_cd)VALUES(1003, NULL, '2003-03-03','F');
INSERT INTO visit_dimension(encounter_num,patient_num,active_status_cd,start_date)VALUES(2001, 1001, NULL, '2011-01-01 01:00:00');
INSERT INTO visit_dimension(encounter_num,patient_num,active_status_cd,start_date)VALUES(2002, 1001, NULL, '2011-01-02 02:00:00');
INSERT INTO visit_dimension(encounter_num,patient_num,active_status_cd,start_date)VALUES(2003, 1001, NULL, '2011-01-03 03:00:00');
INSERT INTO visit_dimension(encounter_num,patient_num,active_status_cd,start_date)VALUES(2004, 1002, NULL, '2011-01-01 01:00:00');
INSERT INTO visit_dimension(encounter_num,patient_num,active_status_cd,start_date)VALUES(2005, 1002, NULL, '2011-01-02 02:00:00');
INSERT INTO observation_fact(encounter_num,patient_num,start_date,concept_cd)VALUES(2001,1001,'2011-01-01 01:01:00','ICD10GM:F30.0');
INSERT INTO observation_fact(encounter_num,patient_num,start_date,concept_cd)VALUES(2001,1001,'2011-01-01 01:02:00','ICD10GM:F30.8');
INSERT INTO observation_fact(encounter_num,patient_num,start_date,concept_cd)VALUES(2002,1001,'2011-01-02 01:01:00','ICD10GM:Y36.9!');
INSERT INTO observation_fact(encounter_num,patient_num,start_date,concept_cd)VALUES(2004,1002,'2011-01-01 01:01:00','ICD10GM:Y36.9!');
COMMIT;
-- demo data for testing query executions via SQL
CREATE TABLE observation_fact(
encounter_num INTEGER NOT NULL,
patient_num INTEGER NOT NULL,
concept_cd VARCHAR(50) NOT NULL,
provider_id VARCHAR(50) NULL,
start_date DATETIME NOT NULL,
modifier_cd VARCHAR(50) NULL,
instance_num INTEGER NULL,
valtype_cd VARCHAR(50) NULL,
tval_char VARCHAR(255) NULL,
nval_num DECIMAL(18,5) NULL,
units_cd VARCHAR(50) NULL,
end_date DATETIME NULL,
location_cd VARCHAR(50) NULL,
update_date DATETIME NULL,
download_date DATETIME NULL,
import_date DATETIME NULL,
sourcesystem_cd VARCHAR(50) NULL
);
CREATE TABLE patient_dimension(
patient_num INTEGER NOT NULL,
vital_status_cd VARCHAR(3) NULL,
birth_date DATETIME NULL,
death_date DATETIME NULL,
sex_cd VARCHAR(8) NULL,
update_date DATETIME NULL,
download_date DATETIME NULL,
import_date DATETIME NULL,
sourcesystem_cd VARCHAR(50) NULL
);
CREATE TABLE patient_mapping(
patient_ide VARCHAR(200) NOT NULL,
patient_ide_source VARCHAR(50) NOT NULL,
patient_num INTEGER NOT NULL,
patient_ide_status VARCHAR(50) NULL,
project_id VARCHAR(50) NOT NULL,
update_date DATETIME NULL,
download_date DATETIME NULL,
import_date DATETIME NULL,
sourcesystem_cd VARCHAR(50) NULL
);
CREATE TABLE visit_dimension(
encounter_num INTEGER NOT NULL,
patient_num INTEGER NOT NULL,
active_status_cd VARCHAR(3) NULL,
start_date DATETIME NULL,
end_date DATETIME NULL,
inout_cd VARCHAR(8) NULL,
location_cd VARCHAR(64) NULL,
update_date DATETIME NULL,
download_date DATETIME NULL,
import_date DATETIME NULL,
sourcesystem_cd VARCHAR(50) NULL
);
-- references to patient_ide, patient_ide_source NULL??
CREATE TABLE encounter_mapping(
encounter_ide VARCHAR(200) NOT NULL,
encounter_ide_source VARCHAR(50) NOT NULL,
project_id VARCHAR(50) NOT NULL,
encounter_num INTEGER NOT NULL,
patient_ide VARCHAR(200) NULL,
patient_ide_source VARCHAR(50) NULL,
encounter_ide_status VARCHAR(50) NULL,
update_date DATETIME NULL,
download_date DATETIME NULL,
import_date DATETIME NULL,
sourcesystem_cd VARCHAR(50) NULL
);
DROP TABLE observation_fact;
DROP TABLE patient_dimension;
DROP TABLE visit_dimension;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment