2016-09-13 10:52:27 +02:00
package org.hwo.pulscounter.db ;
2016-09-20 09:22:29 +02:00
import java.io.BufferedReader ;
import java.io.IOException ;
import java.io.InputStream ;
import java.io.InputStreamReader ;
2016-09-13 10:52:27 +02:00
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.PreparedStatement ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
2016-09-15 16:52:11 +02:00
import java.util.LinkedList ;
import java.util.List ;
import java.util.UUID ;
2016-09-13 10:52:27 +02:00
import org.hwo.pulscounter.SnapShot ;
import static org.hwo.logging.Logging.* ;
import static org.hwo.logging.LogLevel.* ;
public class PulsCounterDatabase {
private Connection dbConnection ;
public PulsCounterDatabase ( ) {
try {
getClass ( ) . getClassLoader ( ) . loadClass ( "org.hsqldb.jdbcDriver" ) ;
dbConnection = DriverManager . getConnection ( "jdbc:hsqldb:file:synololog-hsql" , "SA" , "" ) ;
} catch ( SQLException e ) {
e . printStackTrace ( ) ;
} catch ( ClassNotFoundException e ) {
log ( ERROR , "HyperSQL Driver could not be loaded. [%s]" , e . toString ( ) ) ;
}
2016-09-20 09:22:29 +02:00
InputStream is = getClass ( ) . getResourceAsStream ( "/org/hwo/pulscounter/db/schema/schema.sql" ) ;
if ( is = = null ) {
log ( ERROR , "Database schema file not found" ) ;
} else {
try {
BufferedReader br = new BufferedReader ( new InputStreamReader ( is ) ) ;
do {
String sql = br . readLine ( ) ;
if ( sql = = null ) {
break ;
}
sql = sql . trim ( ) ;
if ( ! sql . equals ( "" ) & & ! sql . startsWith ( "//" ) ) {
log ( sql ) ;
executeSimpleSQL ( sql ) ;
}
} while ( true ) ;
} catch ( IOException e ) {
log ( e ) ;
}
}
2016-09-13 10:52:27 +02:00
}
public void close ( ) {
try {
dbConnection . close ( ) ;
} catch ( SQLException e ) {
log ( ERROR , "Exception while closing database: %s" , e . toString ( ) ) ;
}
}
private ResultSet executeSimpleSQL ( String query , Object . . . args ) {
try {
PreparedStatement stmt = dbConnection . prepareStatement ( query ) ;
for ( int i = 0 ; i < args . length ; i + + ) {
stmt . setObject ( i + 1 , args [ i ] ) ;
}
stmt . execute ( ) ;
ResultSet result = stmt . getResultSet ( ) ;
stmt . closeOnCompletion ( ) ;
return result ;
} catch ( SQLException e ) {
log ( ERROR , "SQL Statement failed: %s" , query ) ;
log ( ERROR , "Exception: %s" , e . toString ( ) ) ;
}
return null ;
}
private String executeVerySimpleQuery ( String query , Object . . . args ) {
ResultSet result = executeSimpleSQL ( query , args ) ;
if ( result ! = null ) {
try {
if ( result . next ( ) ) {
return result . getString ( 1 ) ;
}
} catch ( SQLException e ) {
log ( ERROR , "SQL Statement failed: %s" , query ) ;
log ( ERROR , "Exception: %s" , e . toString ( ) ) ;
}
}
return null ;
}
2016-09-15 16:52:11 +02:00
private Object executeSimpleQueryObject ( String query , Object . . . args ) {
ResultSet result = executeSimpleSQL ( query , args ) ;
if ( result ! = null ) {
try {
if ( result . next ( ) ) {
return result . getObject ( 1 ) ;
}
} catch ( SQLException e ) {
log ( ERROR , "SQL Statement failed: %s" , query ) ;
log ( ERROR , "Exception: %s" , e . toString ( ) ) ;
}
}
return null ;
}
2016-09-13 10:52:27 +02:00
public String getProperty ( String name ) {
2016-09-15 16:52:11 +02:00
return executeVerySimpleQuery ( "SELECT value FROM props WHERE name=?" , name ) ;
2016-09-13 10:52:27 +02:00
}
public void setProperty ( String name , String value ) {
2016-09-15 16:52:11 +02:00
executeSimpleSQL ( "MERGE INTO props USING (VALUES(?,?)) as p(name,value) ON props.name = p.name WHEN MATCHED THEN UPDATE SET props.value = p.value WHEN NOT MATCHED THEN INSERT VALUES uuid(), p.name, p.value" , name , value ) ;
2016-09-13 10:52:27 +02:00
}
public void removeProperty ( String name ) {
2016-09-15 16:52:11 +02:00
executeSimpleSQL ( "DELETE FROM props WHERE props.name = ?" , name ) ;
2016-09-13 10:52:27 +02:00
}
public String getSchemaVersion ( ) {
return getProperty ( "db.schema.version" ) ;
}
public void storeSnapshots ( SnapShot [ ] snapShots ) {
2016-09-13 12:07:01 +02:00
for ( SnapShot snapShot : snapShots ) {
storeSnapshot ( snapShot ) ;
}
}
private void storeSnapshot ( SnapShot snapShot ) {
2016-09-15 16:52:11 +02:00
log ( INFO , "db store snapshot [%d]" , snapShot . getIndex ( ) ) ;
executeVerySimpleQuery ( "INSERT INTO snapshots (id,device,snap_id,timestamp,counters,analogs,inputs,outputs,pullups,inverts,field0) VALUES(uuid(),?,?,?,?,?,?,?,?,?,?)" ,
2016-09-13 12:07:01 +02:00
snapShot . getDeviceSerial ( ) ,
2016-09-15 16:52:11 +02:00
snapShot . getIndex ( ) ,
2016-09-13 12:07:01 +02:00
snapShot . getTimestamp ( ) ,
snapShot . getValues ( ) ,
snapShot . getAnalog ( ) ,
snapShot . getInputmask ( ) ,
snapShot . getOutputmask ( ) ,
snapShot . getPullupmask ( ) ,
2016-09-15 16:52:11 +02:00
snapShot . getInvertmask ( ) ,
snapShot . getField0 ( )
) ;
}
public int highestSnapShot ( int deviceSerial ) {
Integer ind = ( Integer ) executeSimpleQueryObject ( "SELECT max(snap_id) FROM snapshots WHERE device=? GROUP BY device" , deviceSerial ) ;
if ( ind = = null ) {
return - 1 ;
} else {
return ind ;
}
}
public SnapShot [ ] loadSnapshots ( int fromTimestamp ) {
List < SnapShot > snapshots = new LinkedList < > ( ) ;
2016-09-13 12:07:01 +02:00
2016-09-15 16:52:11 +02:00
ResultSet result = executeSimpleSQL ( "SELECT id,device,snap_id,timestamp,counters,analogs,inputs,outputs,pullups,inverts,field0 FROM snapshots WHERE timestamp >= ?" , fromTimestamp ) ;
try {
while ( result . next ( ) ) {
SnapShot ss = new SnapShot ( result ) ;
snapshots . add ( ss ) ;
}
} catch ( SQLException e ) {
log ( e ) ;
}
2016-09-13 10:52:27 +02:00
2016-09-15 16:52:11 +02:00
return snapshots . toArray ( new SnapShot [ 0 ] ) ;
2016-09-13 10:52:27 +02:00
}
}