package org.mxchange.addressbook.database.backend.mysql;
import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.MessageFormat;
import java.util.Iterator;
-import org.mxchange.addressbook.contact.Contact;
import org.mxchange.addressbook.database.backend.BaseDatabaseBackend;
import org.mxchange.addressbook.database.backend.DatabaseBackend;
import org.mxchange.addressbook.database.storage.Storeable;
* @author Roland Haeder
*/
public class MySqlDatabaseBackend extends BaseDatabaseBackend implements DatabaseBackend {
+ /**
+ * An instance of a datbase connection
+ */
+ private static Connection connection;
+
+ /**
+ * Prepared statement for full row count
+ */
+ private PreparedStatement totalRowCount;
+
/**
* Constructor with table name
*
// Validate driver
this.validateDriver("mysql"); //NOI18N
- // Now that the driver is there ...
+ // Now that the driver is there, set the table name
+ this.setTableName(tableName);
}
@Override
- public void connectToDatabase () {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ public void connectToDatabase () throws SQLException {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // Is the connection already there?
+ if (MySqlDatabaseBackend.connection instanceof Connection) {
+ // Already connected
+ this.getLogger().debug("Connection is already established."); //NOI18N
+
+ // No need to connect
+ return;
+ }
+
+ // Generate connection string
+ String connect = String.format("jdbc:mysql://%s/%s", //NOI18N
+ this.getProperty("database.mysql.host"), //NOI18N
+ this.getProperty("database.mysql.dbname") //NOI18N
+ );
+
+ // Debug message
+ this.getLogger().debug(MessageFormat.format("Attempting to connect to {0} ...", connect)); //NOI18N
+
+ // Now get a connection instance back
+ MySqlDatabaseBackend.connection = DriverManager.getConnection(
+ connect,
+ this.getProperty("database.mysql.login"), //NOI18N
+ this.getProperty("database.mysql.password") //NOI18N
+ );
+
+ // Is the connection really up?
+ if (MySqlDatabaseBackend.connection.isClosed()) {
+ // Connection is closed again
+ throw new SQLException("Connection is closed."); //NOI18N
+ }
+
+ // Debug message
+ this.getLogger().debug("Connection is up, preparing some statements ..."); //NOI18N
+
+ // Here, the connection is established, so prepare some statements
+ this.totalRowCount = MySqlDatabaseBackend.connection.prepareStatement(String.format("SELECT COUNT(`id`) AS `cnt` FROM `%s` LIMIT 1", this.getTableName())); //NOI18N
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
}
@Override
- public Iterator<Contact> contactIterator () throws BadTokenException {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ public void doShutdown () {
+ // This should not happen:
+ assert(MySqlDatabaseBackend.connection instanceof Connection) : MessageFormat.format("connection is not valid: {0}", MySqlDatabaseBackend.connection); //NOI18N
+
+ try {
+ // Close down database connection
+ MySqlDatabaseBackend.connection.close();
+ } catch (final SQLException ex) {
+ // Something happened during close()
+ this.abortProgramWithException(ex);
+ }
}
+ /**
+ * Some "getter" for row index from given boolean row value
+ *
+ * @param columnName Name of column
+ * @param bool Boolean value to look for
+ * @return Row index
+ */
@Override
- public void doShutdown () {
+ public int getRowIndexFromColumn (final String columnName, final boolean bool) {
+ throw new UnsupportedOperationException(MessageFormat.format("columnName={0},bool={1}", columnName, bool));
+ }
+
+ @Override
+ public int getTotalCount () throws SQLException {
+ // Trace message
+ this.getLogger().trace(MessageFormat.format("tableName={0} - CALLED!", this.getTableName())); //NOI18N
+
+ // Nothing counted by default
+ int count = 0;
+
+ // Prepared statements are cool ...
+ if (this.totalRowCount.execute()) {
+ // Did fully work, so get result set
+ ResultSet set = this.totalRowCount.getResultSet();
+
+ // First rewind it
+ assert(set.last()) : ": last() failed"; //NOI18N
+
+ // Get integer from 'cnt' alias (see statement)
+ count = set.getInt("cnt"); //NOI18N
+
+ // Debug message
+ this.getLogger().debug(MessageFormat.format("count={0}", count)); //NOI18N
+
+ // Go back to beginning
+ set.beforeFirst();
+ } else {
+ // Empty result
+ this.getLogger().warn(MessageFormat.format("COUNT() query didn't return any result on table {0}.", this.getTableName())); //NOI18N
+ }
+
+ // Trace message
+ this.getLogger().trace(MessageFormat.format("count={0} - EXIT!", count)); //NOI18N
+
+ // Return result
+ return count;
+ }
+
+ /**
+ * Checks whether at least one row is found with given boolean value.
+ *
+ * @param columnName Column to check for boolean value
+ * @param bool Boolean value to check
+ * @return Whether boolean value is found and returns at least one row
+ */
+ @Override
+ public boolean isRowFound (final String columnName, final boolean bool) throws SQLException {
+ // Is at least one entry found?
+ if (this.getTotalCount() == 0) {
+ // No entry found at all
+ return false;
+ }
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ public Iterator<? extends Storeable> iterator () throws BadTokenException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public long length () {
+ throw new UnsupportedOperationException("Not implemented for this backend."); //NOI18N
+ }
+
+ @Override
+ public Storeable readRow (final int rowIndex) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}