diff --git a/pset6/jdbc-example/pom.xml b/pset6/jdbc-example/pom.xml
index 211b901..65d7a0e 100644
--- a/pset6/jdbc-example/pom.xml
+++ b/pset6/jdbc-example/pom.xml
@@ -16,6 +16,11 @@
spring-context
4.0.5.RELEASE
+
+ org.springframework
+ spring-orm
+ 4.0.5.RELEASE
+
org.xerial
@@ -26,28 +31,32 @@
org.hibernate
- hibernate
- 3.5.4-FINAL
+ hibernate-core
+ 4.2.0.Final
+
+ org.hibernate
+ hibernate-annotations
+ 3.5.6-Final
+
-
- dom4j
- dom4j
- 1.6.1
+ org.slf4j
+ slf4j-log4j12
+ 1.7.5
- commons-logging
- commons-logging
- 1.1.1
+ javax.transaction
+ jta
+ 1.1
- commons-collections
- commons-collections
- 3.2.1
+ javassist
+ javassist
+ 3.12.1.GA
@@ -55,7 +64,13 @@
antlr
2.7.7
-
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
\ No newline at end of file
diff --git a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/MetrolinkCommandLineApp.java b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/MetrolinkCommandLineApp.java
index 722e283..784b2f9 100644
--- a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/MetrolinkCommandLineApp.java
+++ b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/MetrolinkCommandLineApp.java
@@ -1,7 +1,9 @@
package com.mikemenne.launchcode;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.stereotype.Component;
import java.util.List;
@@ -10,6 +12,8 @@
* Date: 7/3/14
* Time: 1:51 AM
*/
+
+@Component
public class MetrolinkCommandLineApp {
public static void main(String[] varArgs) {
@@ -26,14 +30,9 @@ private void run() {
}
}
+ @Autowired
private MetrolinkDao metrolinkDao;
+ @Autowired
private AppOutput appOutput;
- public void setMetrolinkDao(MetrolinkDao metrolinkDao) {
- this.metrolinkDao = metrolinkDao;
- }
-
- public void setAppOutput(AppOutput appOutput) {
- this.appOutput = appOutput;
- }
}
diff --git a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/Stop.java b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/Stop.java
index 59370b4..e7546a3 100644
--- a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/Stop.java
+++ b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/Stop.java
@@ -1,5 +1,8 @@
package com.mikemenne.launchcode;
+import javax.persistence.*;
+import static javax.persistence.GenerationType.IDENTITY;
+
import java.util.Date;
/**
@@ -8,9 +11,17 @@
* Time: 1:40 AM
*/
+@Entity
+@Table(name="stops")
public class Stop {
+ @Id
+ @GeneratedValue(strategy = IDENTITY)
+ @Column(name = "stop_id", unique = true, nullable = false)
+ private Integer id;
+ @Column(name = "stop_name")
private String stopName;
+ @Column(name = "stop_desc")
private String stopDescription;
@@ -29,4 +40,12 @@ public String getStopDescription() {
public void setStopDescription(String stopDescription) {
this.stopDescription = stopDescription;
}
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
}
diff --git a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/dao/SqliteJDBCDao.java b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/dao/SqliteJDBCDao.java
index 0dfec3b..6821bad 100644
--- a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/dao/SqliteJDBCDao.java
+++ b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/dao/SqliteJDBCDao.java
@@ -3,47 +3,33 @@
import com.mikemenne.launchcode.AppOutput;
import com.mikemenne.launchcode.MetrolinkDao;
import com.mikemenne.launchcode.Stop;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.hibernate.Criteria;
+import org.hibernate.SessionFactory;
+import org.hibernate.criterion.Restrictions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
+@Repository
public class SqliteJDBCDao implements MetrolinkDao {
- public static final String JDBC_SQLITE_METROLINK_DB = "jdbc:sqlite:metrolink.db";
- public static final String ORG_SQLITE_JDBC = "org.sqlite.JDBC";
-
+ @Autowired
private AppOutput appOutput;
+ @Autowired
+ private SessionFactory sessionFactoryBean;
public List getStopsAllStops() {
- appOutput.print("Fetching metrolink stations...");
- try (Connection connection = getConnection();) {
- PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM stops");
- ResultSet resultSet = preparedStatement.executeQuery();
- List stops = new ArrayList();
- while (resultSet.next()) {
- Stop stop = new Stop();
- stop.setStopName(resultSet.getString("stop_name"));
- stop.setStopDescription(resultSet.getString("stop_desc"));
- stops.add(stop);
- }
- return stops;
- } catch (SQLException e) {
- throw new RuntimeException("Error retrieving stops");
- }
- }
-
- private static Connection getConnection() throws SQLException {
- try {
- Class.forName(ORG_SQLITE_JDBC);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Unable to find class for loading the database", e);
- }
- return DriverManager.getConnection(JDBC_SQLITE_METROLINK_DB);
- }
-
- public void setAppOutput(AppOutput appOutput) {
- this.appOutput = appOutput;
+ sessionFactoryBean.getCurrentSession().beginTransaction();
+ Criteria criteria = sessionFactoryBean.getCurrentSession().createCriteria(Stop.class);
+ List list = criteria.list();
+ sessionFactoryBean.getCurrentSession().getTransaction().commit();
+ return list;
}
}
diff --git a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/util/ScreenOutput.java b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/util/ScreenOutput.java
index 107727a..3a27f40 100644
--- a/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/util/ScreenOutput.java
+++ b/pset6/jdbc-example/src/main/java/com/mikemenne/launchcode/util/ScreenOutput.java
@@ -1,12 +1,15 @@
package com.mikemenne.launchcode.util;
import com.mikemenne.launchcode.AppOutput;
+import org.springframework.stereotype.Service;
/**
* User: mpmenne
* Date: 7/3/14
* Time: 2:04 AM
*/
+
+@Service
public class ScreenOutput implements AppOutput{
@Override
public void print(String output) {
diff --git a/pset6/jdbc-example/src/main/java/org/hibernate/dialect/SQLiteDialect.java b/pset6/jdbc-example/src/main/java/org/hibernate/dialect/SQLiteDialect.java
new file mode 100644
index 0000000..bd108aa
--- /dev/null
+++ b/pset6/jdbc-example/src/main/java/org/hibernate/dialect/SQLiteDialect.java
@@ -0,0 +1,291 @@
+/*
+ * The author disclaims copyright to this source code. In place of
+ * a legal notice, here is a blessing:
+ *
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+ *
+ */
+package org.hibernate.dialect;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.JDBCException;
+import org.hibernate.dialect.function.AbstractAnsiTrimEmulationFunction;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.exception.*;
+import org.hibernate.exception.spi.SQLExceptionConverter;
+import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
+import org.hibernate.type.StandardBasicTypes;
+
+public class SQLiteDialect extends Dialect {
+ public SQLiteDialect() {
+ registerColumnType(Types.BIT, "boolean");
+ registerColumnType(Types.TINYINT, "tinyint");
+ registerColumnType(Types.SMALLINT, "smallint");
+ registerColumnType(Types.INTEGER, "integer");
+ registerColumnType(Types.BIGINT, "bigint");
+ registerColumnType(Types.FLOAT, "float");
+ registerColumnType(Types.REAL, "real");
+ registerColumnType(Types.DOUBLE, "double");
+ registerColumnType(Types.NUMERIC, "numeric($p, $s)");
+ registerColumnType(Types.DECIMAL, "decimal");
+ registerColumnType(Types.CHAR, "char");
+ registerColumnType(Types.VARCHAR, "varchar($l)");
+ registerColumnType(Types.LONGVARCHAR, "longvarchar");
+ registerColumnType(Types.DATE, "date");
+ registerColumnType(Types.TIME, "time");
+ registerColumnType(Types.TIMESTAMP, "datetime");
+ registerColumnType(Types.BINARY, "blob");
+ registerColumnType(Types.VARBINARY, "blob");
+ registerColumnType(Types.LONGVARBINARY, "blob");
+ registerColumnType(Types.BLOB, "blob");
+ registerColumnType(Types.CLOB, "clob");
+ registerColumnType(Types.BOOLEAN, "boolean");
+
+ registerFunction( "concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "") );
+ registerFunction( "mod", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 % ?2" ) );
+ registerFunction( "quote", new StandardSQLFunction("quote", StandardBasicTypes.STRING) );
+ registerFunction( "random", new NoArgSQLFunction("random", StandardBasicTypes.INTEGER) );
+ registerFunction( "round", new StandardSQLFunction("round") );
+ registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
+ registerFunction( "trim", new AbstractAnsiTrimEmulationFunction() {
+ protected SQLFunction resolveBothSpaceTrimFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1)");
+ }
+
+ protected SQLFunction resolveBothSpaceTrimFromFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?2)");
+ }
+
+ protected SQLFunction resolveLeadingSpaceTrimFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "ltrim(?1)");
+ }
+
+ protected SQLFunction resolveTrailingSpaceTrimFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "rtrim(?1)");
+ }
+
+ protected SQLFunction resolveBothTrimFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1, ?2)");
+ }
+
+ protected SQLFunction resolveLeadingTrimFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "ltrim(?1, ?2)");
+ }
+
+ protected SQLFunction resolveTrailingTrimFunction() {
+ return new SQLFunctionTemplate(StandardBasicTypes.STRING, "rtrim(?1, ?2)");
+ }
+ } );
+ }
+
+ @Override
+ public boolean supportsIdentityColumns() {
+ return true;
+ }
+
+ /*
+ public boolean supportsInsertSelectIdentity() {
+ return true; // As specified in NHibernate dialect
+ }
+ */
+
+ @Override
+ public boolean hasDataTypeInIdentityColumn() {
+ return false; // As specified in NHibernate dialect
+ }
+
+ /*
+ public String appendIdentitySelectToInsert(String insertString) {
+ return new StringBuffer(insertString.length()+30). // As specified in NHibernate dialect
+ append(insertString).
+ append("; ").append(getIdentitySelectString()).
+ toString();
+ }
+ */
+
+ @Override
+ public String getIdentityColumnString() {
+ // return "integer primary key autoincrement";
+ return "integer";
+ }
+
+ @Override
+ public String getIdentitySelectString() {
+ return "select last_insert_rowid()";
+ }
+
+ @Override
+ public boolean supportsLimit() {
+ return true;
+ }
+
+ @Override
+ public boolean bindLimitParametersInReverseOrder() {
+ return true;
+ }
+
+ @Override
+ protected String getLimitString(String query, boolean hasOffset) {
+ return query + (hasOffset ? " limit ? offset ?" : " limit ?");
+ }
+
+ @Override
+ public boolean supportsTemporaryTables() {
+ return true;
+ }
+
+ @Override
+ public String getCreateTemporaryTableString() {
+ return "create temporary table if not exists";
+ }
+
+ @Override
+ public Boolean performTemporaryTableDDLInIsolation() {
+ return Boolean.FALSE;
+ }
+
+ /*
+ @Override
+ public boolean dropTemporaryTableAfterUse() {
+ return true; // temporary tables are only dropped when the connection is closed. If the connection is pooled...
+ }
+ */
+
+ @Override
+ public boolean supportsCurrentTimestampSelection() {
+ return true;
+ }
+
+ @Override
+ public boolean isCurrentTimestampSelectStringCallable() {
+ return false;
+ }
+
+ @Override
+ public String getCurrentTimestampSelectString() {
+ return "select current_timestamp";
+ }
+
+ private static final int SQLITE_BUSY = 5;
+ private static final int SQLITE_LOCKED = 6;
+ private static final int SQLITE_IOERR = 10;
+ private static final int SQLITE_CORRUPT = 11;
+ private static final int SQLITE_NOTFOUND = 12;
+ private static final int SQLITE_FULL = 13;
+ private static final int SQLITE_CANTOPEN = 14;
+ private static final int SQLITE_PROTOCOL = 15;
+ private static final int SQLITE_TOOBIG = 18;
+ private static final int SQLITE_CONSTRAINT = 19;
+ private static final int SQLITE_MISMATCH = 20;
+ private static final int SQLITE_NOTADB = 26;
+ @Override
+ public SQLExceptionConverter buildSQLExceptionConverter() {
+ return new SQLExceptionConverter() {
+ @Override
+ public JDBCException convert(SQLException sqlException, String message, String sql) {
+ final int errorCode = org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode(sqlException);
+ if (errorCode == SQLITE_CONSTRAINT) {
+ final String constraintName = EXTRACTER.extractConstraintName(sqlException);
+ return new ConstraintViolationException(message, sqlException, sql, constraintName);
+ } else if (errorCode == SQLITE_TOOBIG || errorCode == SQLITE_MISMATCH) {
+ return new DataException(message, sqlException, sql);
+ } else if (errorCode == SQLITE_BUSY || errorCode == SQLITE_LOCKED) {
+ return new LockAcquisitionException(message, sqlException, sql);
+ } else if ((errorCode >= SQLITE_IOERR && errorCode <= SQLITE_PROTOCOL) || errorCode == SQLITE_NOTADB) {
+ return new JDBCConnectionException(message, sqlException, sql);
+ }
+ return new GenericJDBCException(message, sqlException, sql);
+ }
+ };
+ }
+
+ public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+ public String extractConstraintName(SQLException sqle) {
+ return extractUsingTemplate( "constraint ", " failed", sqle.getMessage() );
+ }
+ };
+
+ @Override
+ public boolean supportsUnionAll() {
+ return true;
+ }
+
+ @Override
+ public boolean hasAlterTable() {
+ return false; // As specified in NHibernate dialect
+ }
+
+ @Override
+ public boolean dropConstraints() {
+ return false;
+ }
+
+ /*
+ public String getAddColumnString() {
+ return "add column";
+ }
+ */
+
+ @Override
+ public String getForUpdateString() {
+ return "";
+ }
+
+ @Override
+ public boolean supportsOuterJoinForUpdate() {
+ return false;
+ }
+
+ @Override
+ public String getDropForeignKeyString() {
+ throw new UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect");
+ }
+
+ @Override
+ public String getAddForeignKeyConstraintString(String constraintName,
+ String[] foreignKey, String referencedTable, String[] primaryKey,
+ boolean referencesPrimaryKey) {
+ throw new UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect");
+ }
+
+ @Override
+ public String getAddPrimaryKeyConstraintString(String constraintName) {
+ throw new UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect");
+ }
+
+ @Override
+ public boolean supportsIfExistsBeforeTableName() {
+ return true;
+ }
+
+ /*
+ public boolean supportsCascadeDelete() {
+ return true;
+ }
+ */
+
+ /* not case insensitive for unicode characters by default (ICU extension needed)
+ public boolean supportsCaseInsensitiveLike() {
+ return true;
+ }
+ */
+
+ @Override
+ public boolean supportsTupleDistinctCounts() {
+ return false;
+ }
+
+ @Override
+ public String getSelectGUIDString() {
+ return "select hex(randomblob(16))";
+ }
+}
\ No newline at end of file
diff --git a/pset6/jdbc-example/src/main/resources/application-context.xml b/pset6/jdbc-example/src/main/resources/application-context.xml
index 957b848..2fccb03 100644
--- a/pset6/jdbc-example/src/main/resources/application-context.xml
+++ b/pset6/jdbc-example/src/main/resources/application-context.xml
@@ -2,40 +2,48 @@
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd
+ http://www.springframework.org/schema/aop
+ http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+ http://www.springframework.org/schema/tx
+ http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
-
-
-
+
-
+
-
-
-
+
+ class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
+
-
-
+
+
+ com.mikemenne.launchcode.Stop
+
- org.hibernate.dialect.MySQLDialect
- true
+ org.hibernate.dialect.SQLiteDialect
+ thread
+
-
-
- /hibernate/Stock.hbm.xml
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pset6/jdbc-example/src/main/resources/log4j.properties b/pset6/jdbc-example/src/main/resources/log4j.properties
new file mode 100644
index 0000000..89a5596
--- /dev/null
+++ b/pset6/jdbc-example/src/main/resources/log4j.properties
@@ -0,0 +1,59 @@
+
+# Define the root logger with appender file
+log4j.rootLogger = DEBUG, FILE
+
+# logs from application code
+log4j.logger.com.mikemenne.launchcode = ALL, FILE, stdout
+
+# logs from Spring code
+log4j.logger.org.springframework = ALL, SPRING
+log4j.additivity.org.springframework = false
+
+# logs from hibernate libraries
+log4j.logger.org.hibernate = ALL, HBM
+log4j.additivity.org.hibernate = false
+
+# logs from hibernate spring
+log4j.logger.org.springframework.orm = ALL, HBM-SPRING
+log4j.additivity.org.springframework.orm = false
+
+# Define the file appender
+log4j.appender.FILE=org.apache.log4j.RollingFileAppender
+# Set the name of the file
+log4j.appender.FILE.File=metrolink.log
+# Set the immediate flush to true (default)
+log4j.appender.FILE.ImmediateFlush=true
+# Set the threshold to debug mode
+#log4j.appender.FILE.Threshold=debug
+# Set the append to false, overwrite
+log4j.appender.FILE.Append=false
+# Define the layout for file appender
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.conversionPattern=%d{ISO8601} %-5p %c ~ %m%n
+
+# appender for spring logs
+log4j.appender.SPRING = org.apache.log4j.RollingFileAppender
+log4j.appender.SPRING.layout = org.apache.log4j.PatternLayout
+log4j.appender.SPRING.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
+log4j.appender.SPRING.File = spring.log
+log4j.appender.SPRING.Append=false
+
+# appender for hibernate logs
+log4j.appender.HBM = org.apache.log4j.RollingFileAppender
+log4j.appender.HBM.layout = org.apache.log4j.PatternLayout
+log4j.appender.HBM.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
+log4j.appender.HBM.File = hbm.log
+log4j.appender.HBM.Append=false
+
+# appender for hibernate logs
+log4j.appender.HBM-SPRING = org.apache.log4j.RollingFileAppender
+log4j.appender.HBM-SPRING.layout = org.apache.log4j.PatternLayout
+log4j.appender.HBM-SPRING.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
+log4j.appender.HBM-SPRING.File = hbm-spring.log
+log4j.appender.HBM-SPRING.Append=false
+
+# appender for logs to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n