--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.LinkedList;
+
+public class MDatabaseConnection extends MObject {
+
+ public static enum TransactionStatus {
+ CLOSED,
+ SUCCESSFUL,
+ FAILED
+ };
+
+ protected String driver = null;
+ protected String url = null;
+ protected String username = null;
+ protected String password = null;
+
+ protected Connection connection = null;
+
+ protected MDatabaseConnection.TransactionStatus transactionStatus = MDatabaseConnection.TransactionStatus.CLOSED;
+
+ /* */
+
+ public MDatabaseConnection(String driver, String url, String username, String password) throws MDatabaseConnectionFailureException {
+ super();
+ //
+ if (MText.isBlank(driver)) {
+ throw new IllegalArgumentException("Invalid 'driver': null or empty.");
+ }
+ if (MText.isBlank(url)) {
+ throw new IllegalArgumentException("Invalid 'url': null or empty.");
+ }
+ if (null == username) {
+ throw new IllegalArgumentException("Invalid 'username': null.");
+ }
+ if (null == password) {
+ throw new IllegalArgumentException("Invalid 'password': null.");
+ }
+ //
+ this.driver = driver;
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ // Load driver.
+ try {
+ Class.forName(this.getDriver()).newInstance();
+ }
+ catch (ClassNotFoundException exception) {
+ throw new MDatabaseConnectionFailureException("Could not load driver.", exception);
+ }
+ catch (IllegalAccessException exception) {
+ throw new MDatabaseConnectionFailureException("Could not load driver.", exception);
+ }
+ catch (InstantiationException exception) {
+ throw new MDatabaseConnectionFailureException("Could not load driver.", exception);
+ }
+ // Establish a connection.
+ try {
+ this.connection = DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword());
+ }
+ catch (SQLException exception) {
+ throw new MDatabaseConnectionFailureException("Could not get database connection.", exception);
+ }
+ // Set SQL mode to standard ANSI.
+ try {
+ this.getConnection().createStatement().executeUpdate("SET SQL_MODE='ANSI'");
+ }
+ catch (SQLException exception) {
+ throw new MDatabaseConnectionFailureException("Could not set SQL mode to ANSI.", exception);
+ }
+ }
+
+ public void close() throws MDatabaseConnectionFailureException {
+ try {
+ this.getConnection().close();
+ }
+ catch (SQLException exception) {
+ throw new MDatabaseConnectionFailureException("Could not close database connection.", exception);
+ }
+ }
+
+ public boolean isClosed() throws MDatabaseConnectionFailureException {
+ try {
+ return this.getConnection().isClosed();
+ }
+ catch (SQLException exception) {
+ throw new MDatabaseConnectionFailureException("Could not determine the state.", exception);
+ }
+ }
+
+ protected void finalize() {
+ try {
+ this.close();
+ }
+ catch (Exception exception) {
+ }
+ }
+
+ /* Driver. */
+
+ public String getDriver() {
+ return this.driver;
+ }
+
+ /* Url. */
+
+ public String getUrl() {
+ return this.url;
+ }
+
+ /* Username. */
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ /* Password. */
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ /* Connection. */
+
+ protected Connection getConnection() {
+ return this.connection;
+ }
+
+ /* Transactions. */
+
+ protected void setTransactionStatus(MDatabaseConnection.TransactionStatus transactionStatus) {
+ if (null == transactionStatus) {
+ throw new IllegalArgumentException("Invalid 'transactionStatus': null.");
+ }
+ //
+ this.transactionStatus = transactionStatus;
+ }
+
+ public MDatabaseConnection.TransactionStatus getTransactionStatus() {
+ return this.transactionStatus;
+ }
+
+ public void startTransaction() throws MSqlTransactionException {
+ if (MDatabaseConnection.TransactionStatus.CLOSED != this.getTransactionStatus()) {
+ throw new MSqlTransactionException("Nested transactions not allowed.");
+ }
+ try {
+ this.getConnection().setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+ this.getConnection().setAutoCommit(false);
+ this.setTransactionStatus(MDatabaseConnection.TransactionStatus.SUCCESSFUL);
+ }
+ catch (SQLException exception) {
+ throw new MSqlTransactionException("Could not start transaction.", exception);
+ }
+ }
+
+ public void rollBackTransaction() throws MSqlTransactionException {
+ if (MDatabaseConnection.TransactionStatus.CLOSED == this.getTransactionStatus()) {
+ throw new MSqlTransactionException("Transaction not started.");
+ }
+ try {
+ this.getConnection().rollback();
+ this.getConnection().setAutoCommit(true);
+ this.setTransactionStatus(MDatabaseConnection.TransactionStatus.CLOSED);
+ }
+ catch (SQLException exception) {
+ this.setTransactionStatus(MDatabaseConnection.TransactionStatus.FAILED);
+ throw new MSqlTransactionException("Could not roll back transaction.", exception);
+ }
+ }
+
+ public MDatabaseConnection.TransactionStatus commitTransaction() throws MSqlTransactionException {
+ switch (this.getTransactionStatus()) {
+ case SUCCESSFUL:
+ try {
+ this.getConnection().commit();
+ this.getConnection().setAutoCommit(true);
+ this.setTransactionStatus(MDatabaseConnection.TransactionStatus.CLOSED);
+ return MDatabaseConnection.TransactionStatus.SUCCESSFUL;
+ }
+ catch (SQLException exception) {
+ this.rollBackTransaction();
+ return MDatabaseConnection.TransactionStatus.FAILED;
+ }
+ case FAILED:
+ this.rollBackTransaction();
+ return MDatabaseConnection.TransactionStatus.FAILED;
+ default: // instead of "case CLOSED:" (necessary to avoid Java compilation errors)
+ throw new MSqlTransactionException("Transaction not started.");
+ }
+ }
+
+ /* Statements. */
+
+ public MSqlStatementResults executePreparedStatement(String statement) throws MSqlStatementException {
+ return this.executePreparedStatement(statement, new LinkedList<Object>());
+ }
+
+ public MSqlStatementResults executePreparedStatement(String statement, LinkedList<Object> parameters) throws MSqlStatementException {
+ if (MText.isBlank(statement)) {
+ throw new IllegalArgumentException("Invalid 'statement': null or empty.");
+ }
+ if (null == parameters) {
+ throw new IllegalArgumentException("Invalid 'parameters': null.");
+ }
+ //
+ MSqlStatementResults results = null;
+ PreparedStatement preparedStatement = null;
+ try {
+ // Prepare the statement.
+ preparedStatement = this.getConnection().prepareStatement(statement, PreparedStatement.RETURN_GENERATED_KEYS);
+ for (int p = 0; parameters.size() > p; p++) {
+ preparedStatement.setObject(p + 1, parameters.get(p));
+ }
+ // Execute the statement and parse the results.
+ preparedStatement.execute();
+ results = new MSqlStatementResults(preparedStatement);
+ }
+ catch (SQLException exception) {
+ if (MDatabaseConnection.TransactionStatus.SUCCESSFUL == this.getTransactionStatus()) {
+ this.setTransactionStatus(MDatabaseConnection.TransactionStatus.FAILED);
+ }
+ throw new MSqlStatementException(String.format("Could not execute prepared statement: %s.", preparedStatement), exception);
+ }
+ return results;
+ }
+
+ /* Tables. */
+
+ public MSqlTable getTable(String table, String primaryKey) {
+ return new MSqlTable(this, table, primaryKey);
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+@SuppressWarnings("serial")
+public class MDatabaseConnectionFailureException extends MDatabaseException {
+
+ /* */
+
+ public MDatabaseConnectionFailureException() {
+ super();
+ }
+
+ public MDatabaseConnectionFailureException(String message) {
+ super(message);
+ }
+
+ public MDatabaseConnectionFailureException(Throwable error) {
+ super(error);
+ }
+
+ public MDatabaseConnectionFailureException(String message, Throwable error) {
+ super(message, error);
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+
+public class MDatabaseConnectionGenerator extends MObject {
+
+ protected String driver = null;
+ protected String url = null;
+ protected String username = null;
+ protected String password = null;
+
+ /* */
+
+ public MDatabaseConnectionGenerator(String driver, String url, String username, String password) {
+ super();
+ //
+ if (MText.isBlank(driver)) {
+ throw new IllegalArgumentException("Invalid 'driver': null or empty.");
+ }
+ if (MText.isBlank(url)) {
+ throw new IllegalArgumentException("Invalid 'url': null or empty.");
+ }
+ if (null == username) {
+ throw new IllegalArgumentException("Invalid 'username': null.");
+ }
+ if (null == password) {
+ throw new IllegalArgumentException("Invalid 'password': null.");
+ }
+ //
+ this.driver = driver;
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ /* Driver. */
+
+ public String getDriver() {
+ return this.driver;
+ }
+
+ /* Url. */
+
+ public String getUrl() {
+ return this.url;
+ }
+
+ /* Username. */
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ /* Password. */
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ /* Generator. */
+
+ public MDatabaseConnection getNewDatabaseConnection() throws MDatabaseConnectionFailureException {
+ return new MDatabaseConnection(this.getDriver(), this.getUrl(), this.getUsername(), this.getPassword());
+ }
+
+ public boolean isGeneratorFor(MDatabaseConnection databaseConnection) {
+ if (null == databaseConnection) {
+ throw new IllegalArgumentException("Invalid 'databaseConnection': null.");
+ }
+ //
+ if (!databaseConnection.getDriver().equals(this.getDriver())) {
+ return false;
+ }
+ if (!databaseConnection.getUrl().equals(this.getUrl())) {
+ return false;
+ }
+ if (!databaseConnection.getUsername().equals(this.getUsername())) {
+ return false;
+ }
+ if (!databaseConnection.getPassword().equals(this.getPassword())) {
+ return false;
+ }
+ //
+ return true;
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+import com.marcozanon.macaco.MObject;
+import java.util.LinkedList;
+
+public class MDatabaseConnectionPool extends MObject {
+
+ protected MDatabaseConnectionGenerator databaseConnectionGenerator = null;
+
+ protected LinkedList<MDatabaseConnection> databaseConnections = new LinkedList<MDatabaseConnection>();
+ protected int minimumSize = 0;
+ protected int maximumSize = 0;
+
+ /* */
+
+ public MDatabaseConnectionPool(String driver, String url, String username, String password, int minimumSize, int maximumSize) throws MDatabaseConnectionFailureException {
+ super();
+ //
+ if (0 > minimumSize) {
+ throw new IllegalArgumentException(String.format("Invalid 'minimumSize': %s.", minimumSize));
+ }
+ if (1 > maximumSize) {
+ throw new IllegalArgumentException(String.format("Invalid 'maximumSize': %s.", maximumSize));
+ }
+ else if (minimumSize > maximumSize) {
+ throw new IllegalArgumentException(String.format("Invalid 'maximumSize': %s < %s ('minimumSize').", maximumSize, minimumSize));
+ }
+ //
+ this.databaseConnectionGenerator = new MDatabaseConnectionGenerator(driver, url, username, password);
+ this.minimumSize = minimumSize;
+ this.maximumSize = maximumSize;
+ //
+ this.initialize();
+ }
+
+ protected void initialize() throws MDatabaseConnectionFailureException {
+ for (int c = 0; c < this.getMinimumSize(); c++) {
+ MDatabaseConnection databaseConnection = this.getDatabaseConnectionGenerator().getNewDatabaseConnection();
+ this.pushDatabaseConnection(databaseConnection);
+ }
+ }
+
+ /* Database connection generator. */
+
+ protected MDatabaseConnectionGenerator getDatabaseConnectionGenerator() {
+ return this.databaseConnectionGenerator;
+ }
+
+ /* Database connections. */
+
+ protected LinkedList<MDatabaseConnection> getDatabaseConnections() {
+ return this.databaseConnections;
+ }
+
+ protected int getMinimumSize() {
+ return this.minimumSize;
+ }
+
+ protected int getMaximumSize() {
+ return this.maximumSize;
+ }
+
+ public synchronized MDatabaseConnection popDatabaseConnection() throws MDatabaseConnectionFailureException {
+ LinkedList<MDatabaseConnection> databaseConnections = this.getDatabaseConnections();
+ MDatabaseConnection databaseConnection = databaseConnections.removeLast();
+ if (this.getMinimumSize() > databaseConnections.size()) {
+ databaseConnections.add(this.getDatabaseConnectionGenerator().getNewDatabaseConnection());
+ }
+ return databaseConnection;
+ }
+
+ public synchronized void pushDatabaseConnection(MDatabaseConnection databaseConnection) throws MDatabaseConnectionFailureException {
+ if (null == databaseConnection) {
+ throw new IllegalArgumentException("Invalid 'databaseConnection': null.");
+ }
+ else if (!this.getDatabaseConnectionGenerator().isGeneratorFor(databaseConnection)) {
+ throw new IllegalArgumentException("Invalid 'databaseConnection': not compatible with this database connection pool.");
+ }
+ else if (databaseConnection.isClosed()) {
+ throw new IllegalArgumentException("Invalid 'databaseConnection': closed.");
+ }
+ //
+ LinkedList<MDatabaseConnection> databaseConnections = this.getDatabaseConnections();
+ if (this.getMaximumSize() >= databaseConnections.size()) {
+ databaseConnections.add(databaseConnection);
+ }
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+import com.marcozanon.macaco.MException;
+
+public abstract class MDatabaseException extends MException {
+
+ /* */
+
+ public MDatabaseException() {
+ super();
+ }
+
+ public MDatabaseException(String message) {
+ super(message);
+ }
+
+ public MDatabaseException(Throwable error) {
+ super(error);
+ }
+
+ public MDatabaseException(String message, Throwable error) {
+ super(message, error);
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+@SuppressWarnings("serial")
+public class MSqlStatementException extends MDatabaseException {
+
+ /* */
+
+ public MSqlStatementException() {
+ super();
+ }
+
+ public MSqlStatementException(String message) {
+ super(message);
+ }
+
+ public MSqlStatementException(Throwable error) {
+ super(error);
+ }
+
+ public MSqlStatementException(String message, Throwable error) {
+ super(message, error);
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+
+public class MSqlStatementResults extends MObject {
+
+ protected PreparedStatement preparedStatement = null;
+ protected ResultSet resultSet = null;
+
+ protected LinkedList<LinkedHashMap<String, Object>> records = new LinkedList<LinkedHashMap<String, Object>>();
+
+ protected LinkedHashSet<Object> generatedKeys = new LinkedHashSet<Object>();
+
+ /* */
+
+ public MSqlStatementResults(PreparedStatement preparedStatement) throws MSqlStatementException {
+ super();
+ //
+ if (null == preparedStatement) {
+ throw new IllegalArgumentException("Invalid 'preparedStatement': null.");
+ }
+ //
+ this.preparedStatement = preparedStatement;
+ //
+ try {
+ this.resultSet = this.getPreparedStatement().getResultSet();
+ if (null != this.getResultSet()) {
+ while (this.getResultSet().next()) {
+ ResultSetMetaData resultSetMetaData = this.getResultSet().getMetaData();
+ LinkedHashMap<String, Object> record = new LinkedHashMap<String, Object>();
+ for (int f = 0; resultSetMetaData.getColumnCount() > f; f++) {
+ String field = resultSetMetaData.getColumnLabel(f + 1);
+ record.put(field, this.getResultSet().getObject(field));
+ }
+ this.getRecords().add(record);
+ }
+ }
+ }
+ catch (SQLException exception) {
+ throw new MSqlStatementException("Could not retrieve statement records.", exception);
+ }
+ //
+ try {
+ ResultSet generatedKeysResultSet = this.getPreparedStatement().getGeneratedKeys();
+ while (generatedKeysResultSet.next()) {
+ this.getGeneratedKeys().add(generatedKeysResultSet.getObject(1));
+ }
+ generatedKeysResultSet.close();
+ }
+ catch (SQLException exception) {
+ throw new MSqlStatementException("Could not retrieve generated keys.", exception);
+ }
+ }
+
+ public void close() throws MDatabaseConnectionFailureException {
+ try {
+ if (null != this.getResultSet()) {
+ this.getResultSet().close();
+ }
+ this.getPreparedStatement().close();
+ }
+ catch (SQLException exception) {
+ throw new MDatabaseConnectionFailureException("Could not close statement and/or result set references.", exception);
+ }
+ }
+
+ protected void finalize() {
+ try {
+ this.close();
+ }
+ catch (Exception exception) {
+ }
+ }
+
+ /* References. */
+
+ protected PreparedStatement getPreparedStatement() {
+ return this.preparedStatement;
+ }
+
+ public ResultSet getResultSet() {
+ return this.resultSet;
+ }
+
+ /* Records. */
+
+ public LinkedList<LinkedHashMap<String, Object>> getRecords() {
+ return this.records;
+ }
+
+ public LinkedList<Object> getRecordsByField(String field) {
+ if (MText.isBlank(field)) {
+ throw new IllegalArgumentException("Invalid 'field': null or empty.");
+ }
+ //
+ LinkedList<Object> recordsByField = new LinkedList<Object>();
+ for (LinkedHashMap<String, Object> record: this.getRecords()) {
+ Object r = record.get(field);
+ if (null == r) {
+ throw new IllegalArgumentException(String.format("Invalid 'field': %s.", field));
+ }
+ recordsByField.add(r);
+ }
+ return recordsByField;
+ }
+
+ /* Generated keys. */
+
+ public LinkedHashSet<Object> getGeneratedKeys() {
+ return this.generatedKeys;
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+import com.marcozanon.macaco.MObject;
+import com.marcozanon.macaco.text.MText;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+
+public class MSqlTable extends MObject {
+
+ protected MDatabaseConnection databaseConnection = null;
+ protected String table = null;
+ protected String primaryKey = null;
+
+ /* */
+
+ public MSqlTable(MDatabaseConnection databaseConnection, String table, String primaryKey) {
+ super();
+ //
+ if (null == databaseConnection) {
+ throw new IllegalArgumentException("Invalid 'databaseConnection': null.");
+ }
+ if (MText.isBlank(table)) {
+ throw new IllegalArgumentException("Invalid 'table': null or empty.");
+ }
+ if (MText.isBlank(primaryKey)) {
+ throw new IllegalArgumentException("Invalid 'primaryKey': null or empty.");
+ }
+ //
+ this.databaseConnection = databaseConnection;
+ this.table = table;
+ this.primaryKey = primaryKey;
+ }
+
+ /* Database connection. */
+
+ protected MDatabaseConnection getDatabaseConnection() {
+ return this.databaseConnection;
+ }
+
+ /* Table. */
+
+ public String getTable() {
+ return this.table;
+ }
+
+ /* Primary key. */
+
+ public String getPrimaryKey() {
+ return this.primaryKey;
+ }
+
+ /* Statements. */
+
+ protected MSqlStatementResults insertRecord(LinkedHashMap<String, Object> map) throws MSqlStatementException {
+ if (null == map) {
+ throw new IllegalArgumentException("Invalid 'map': null.");
+ }
+ //
+ LinkedList<Object> p = new LinkedList<Object>();
+ StringBuilder fields = new StringBuilder("");
+ StringBuilder s = new StringBuilder("");
+ for (String field: map.keySet()) {
+ fields.append("\"" + this.getTable() + "\".\"" + field + "\", ");
+ s.append("?, ");
+ p.add(map.get(field));
+ }
+ fields.delete(fields.length() - 2, fields.length());
+ s.delete(s.length() - 2, s.length());
+ return this.getDatabaseConnection().executePreparedStatement(" INSERT INTO \"" + this.getTable() + "\""
+ + " (" + fields + ")"
+ + " VALUES (" + s + ")",
+ p);
+ }
+
+ protected MSqlStatementResults updateRecord(LinkedHashMap<String, Object> map, Object id) throws MSqlStatementException {
+ if (null == map) {
+ throw new IllegalArgumentException("Invalid 'map': null.");
+ }
+ if (null == id) {
+ throw new IllegalArgumentException("Invalid 'id': null.");
+ }
+ //
+ LinkedList<Object> p = new LinkedList<Object>();
+ StringBuilder s = new StringBuilder("");
+ for (String field: map.keySet()) {
+ s.append("\"" + this.getTable() + "\".\"" + field + "\" = ?, ");
+ p.add(map.get(field));
+ }
+ s.delete(s.length() - 2, s.length());
+ p.add(id);
+ return this.getDatabaseConnection().executePreparedStatement(" UPDATE \"" + this.getTable() + "\""
+ + " SET " + s
+ + " WHERE (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)",
+ p);
+ }
+
+ public MSqlStatementResults setRecord(LinkedHashMap<String, Object> map, Object id) throws MSqlStatementException {
+ if (null == id) {
+ return this.insertRecord(map);
+ }
+ else {
+ return this.updateRecord(map, id);
+ }
+ }
+
+ public MSqlStatementResults getRecord(Object id) throws MSqlStatementException {
+ if (null == id) {
+ throw new IllegalArgumentException("Invalid 'id': null.");
+ }
+ //
+ LinkedList<Object> p = new LinkedList<Object>();
+ p.add(id);
+ return this.getDatabaseConnection().executePreparedStatement(" SELECT *"
+ + " FROM \"" + this.getTable() + "\""
+ + " WHERE (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)",
+ p);
+ }
+
+ public MSqlStatementResults deleteRecord(Object id) throws MSqlStatementException {
+ if (null == id) {
+ throw new IllegalArgumentException("Invalid 'id': null.");
+ }
+ //
+ LinkedList<Object> p = new LinkedList<Object>();
+ p.add(id);
+ return this.getDatabaseConnection().executePreparedStatement(" DELETE FROM \"" + this.getTable() + "\""
+ + " WHERE (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)",
+ p);
+ }
+
+ public MSqlStatementResults deleteRecords(LinkedHashSet idSet) throws MSqlStatementException {
+ if (null == idSet) {
+ throw new IllegalArgumentException("Invalid 'idSet': null.");
+ }
+ //
+ StringBuilder whereClause = new StringBuilder("(0)");
+ LinkedList<Object> p = new LinkedList<Object>();
+ for (Object id: idSet) {
+ whereClause.append(" OR (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)");
+ p.add(id);
+ }
+ return this.getDatabaseConnection().executePreparedStatement(" DELETE FROM \"" + this.getTable() + "\""
+ + " WHERE (" + whereClause + ")",
+ p);
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.database;
+
+@SuppressWarnings("serial")
+public class MSqlTransactionException extends MDatabaseException {
+
+ /* */
+
+ public MSqlTransactionException() {
+ super();
+ }
+
+ public MSqlTransactionException(String message) {
+ super(message);
+ }
+
+ public MSqlTransactionException(Throwable error) {
+ super(error);
+ }
+
+ public MSqlTransactionException(String message, Throwable error) {
+ super(message, error);
+ }
+
+}
package com.marcozanon.macaco.logging;
-import com.marcozanon.macaco.sql.MSqlConnection;
-import com.marcozanon.macaco.sql.MSqlConnectionFailureException;
-import com.marcozanon.macaco.sql.MSqlConnectionPool;
-import com.marcozanon.macaco.sql.MSqlStatementException;
-import com.marcozanon.macaco.sql.MSqlTable;
+import com.marcozanon.macaco.database.MDatabaseConnection;
+import com.marcozanon.macaco.database.MDatabaseConnectionFailureException;
+import com.marcozanon.macaco.database.MDatabaseConnectionPool;
+import com.marcozanon.macaco.database.MSqlStatementException;
+import com.marcozanon.macaco.database.MSqlTable;
import com.marcozanon.macaco.text.MText;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MLogDatabaseTable extends MLogTarget {
- protected MSqlConnectionPool sqlConnectionPool = null;
+ protected MDatabaseConnectionPool databaseConnectionPool = null;
protected String logDatabaseTable = null;
protected String logDatabaseTablePrimaryKey = null;
protected String logDatabaseField = null;
- protected MSqlConnection sqlConnection = null;
+ protected MDatabaseConnection databaseConnection = null;
/* */
- public MLogDatabaseTable(MSqlConnectionPool sqlConnectionPool, String logDatabaseTable, String logDatabaseTablePrimaryKey, String logDatabaseField) throws MLoggingException {
+ public MLogDatabaseTable(MDatabaseConnectionPool databaseConnectionPool, String logDatabaseTable, String logDatabaseTablePrimaryKey, String logDatabaseField) throws MLoggingException {
super();
//
- if (null == sqlConnectionPool) {
- throw new IllegalArgumentException("Invalid 'sqlConnectionPool': null.");
+ if (null == databaseConnectionPool) {
+ throw new IllegalArgumentException("Invalid 'databaseConnectionPool': null.");
}
if (MText.isEmpty(logDatabaseTable)) {
throw new IllegalArgumentException("Invalid 'logDatabaseTable': null or empty.");
throw new IllegalArgumentException("Invalid 'logDatabaseField': null or empty.");
}
//
- this.sqlConnectionPool = sqlConnectionPool;
+ this.databaseConnectionPool = databaseConnectionPool;
this.logDatabaseTable = logDatabaseTable;
this.logDatabaseTablePrimaryKey = logDatabaseTablePrimaryKey;
this.logDatabaseField = logDatabaseField;
public void close() throws MLoggingException {
}
- /* Sql connection pool. */
+ /* Database connection pool. */
- protected MSqlConnectionPool getSqlConnectionPool() {
- return this.sqlConnectionPool;
+ protected MDatabaseConnectionPool getDatabaseConnectionPool() {
+ return this.databaseConnectionPool;
}
/* Database logging parameters. */
separator.append(" ");
}
//
- MSqlConnection sqlConnection = this.getSqlConnectionPool().popSqlConnection();
+ MDatabaseConnection databaseConnection = this.getDatabaseConnectionPool().popDatabaseConnection();
//
LinkedHashMap<String, Object> p = new LinkedHashMap<String, Object>();
p.put(this.getLogDatabaseField(), timestamp + separator + message);
- (new MSqlTable(sqlConnection, this.getLogDatabaseTable(), this.getLogDatabaseTablePrimaryKey())).setRecord(p, null);
+ (new MSqlTable(databaseConnection, this.getLogDatabaseTable(), this.getLogDatabaseTablePrimaryKey())).setRecord(p, null);
//
- this.getSqlConnectionPool().pushSqlConnection(sqlConnection);
+ this.getDatabaseConnectionPool().pushDatabaseConnection(databaseConnection);
}
- catch (MSqlConnectionFailureException exception) {
+ catch (MDatabaseConnectionFailureException exception) {
throw new MLoggingException("Could not write to database table.", exception);
}
catch (MSqlStatementException exception) {
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.LinkedList;
-
-public class MSqlConnection extends MObject {
-
- public static enum TransactionStatus {
- CLOSED,
- SUCCESSFUL,
- FAILED
- };
-
- protected String driver = null;
- protected String url = null;
- protected String username = null;
- protected String password = null;
-
- protected Connection connection = null;
-
- protected MSqlConnection.TransactionStatus transactionStatus = MSqlConnection.TransactionStatus.CLOSED;
-
- /* */
-
- public MSqlConnection(String driver, String url, String username, String password) throws MSqlConnectionFailureException {
- super();
- //
- if (MText.isBlank(driver)) {
- throw new IllegalArgumentException("Invalid 'driver': null or empty.");
- }
- if (MText.isBlank(url)) {
- throw new IllegalArgumentException("Invalid 'url': null or empty.");
- }
- if (null == username) {
- throw new IllegalArgumentException("Invalid 'username': null.");
- }
- if (null == password) {
- throw new IllegalArgumentException("Invalid 'password': null.");
- }
- //
- this.driver = driver;
- this.url = url;
- this.username = username;
- this.password = password;
- // Load driver.
- try {
- Class.forName(this.getDriver()).newInstance();
- }
- catch (ClassNotFoundException exception) {
- throw new MSqlConnectionFailureException("Could not load driver.", exception);
- }
- catch (IllegalAccessException exception) {
- throw new MSqlConnectionFailureException("Could not load driver.", exception);
- }
- catch (InstantiationException exception) {
- throw new MSqlConnectionFailureException("Could not load driver.", exception);
- }
- // Establish a connection.
- try {
- this.connection = DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword());
- }
- catch (SQLException exception) {
- throw new MSqlConnectionFailureException("Could not get connection.", exception);
- }
- // Set SQL mode to standard ANSI.
- try {
- this.getConnection().createStatement().executeUpdate("SET SQL_MODE='ANSI'");
- }
- catch (SQLException exception) {
- throw new MSqlConnectionFailureException("Could not set SQL mode to ANSI.", exception);
- }
- }
-
- public void close() throws MSqlConnectionFailureException {
- try {
- this.getConnection().close();
- }
- catch (SQLException exception) {
- throw new MSqlConnectionFailureException("Could not close connection.", exception);
- }
- }
-
- public boolean isClosed() throws MSqlConnectionFailureException {
- try {
- return this.getConnection().isClosed();
- }
- catch (SQLException exception) {
- throw new MSqlConnectionFailureException("Could not determine the state.", exception);
- }
- }
-
- protected void finalize() {
- try {
- this.close();
- }
- catch (Exception exception) {
- }
- }
-
- /* Driver. */
-
- public String getDriver() {
- return this.driver;
- }
-
- /* Url. */
-
- public String getUrl() {
- return this.url;
- }
-
- /* Username. */
-
- public String getUsername() {
- return this.username;
- }
-
- /* Password. */
-
- public String getPassword() {
- return this.password;
- }
-
- /* Connection. */
-
- protected Connection getConnection() {
- return this.connection;
- }
-
- /* Transactions. */
-
- protected void setTransactionStatus(MSqlConnection.TransactionStatus transactionStatus) {
- if (null == transactionStatus) {
- throw new IllegalArgumentException("Invalid 'transactionStatus': null.");
- }
- //
- this.transactionStatus = transactionStatus;
- }
-
- public MSqlConnection.TransactionStatus getTransactionStatus() {
- return this.transactionStatus;
- }
-
- public void startTransaction() throws MSqlTransactionException {
- if (MSqlConnection.TransactionStatus.CLOSED != this.getTransactionStatus()) {
- throw new MSqlTransactionException("Nested transactions not allowed.");
- }
- try {
- this.getConnection().setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
- this.getConnection().setAutoCommit(false);
- this.setTransactionStatus(MSqlConnection.TransactionStatus.SUCCESSFUL);
- }
- catch (SQLException exception) {
- throw new MSqlTransactionException("Could not start transaction.", exception);
- }
- }
-
- public void rollBackTransaction() throws MSqlTransactionException {
- if (MSqlConnection.TransactionStatus.CLOSED == this.getTransactionStatus()) {
- throw new MSqlTransactionException("Transaction not started.");
- }
- try {
- this.getConnection().rollback();
- this.getConnection().setAutoCommit(true);
- this.setTransactionStatus(MSqlConnection.TransactionStatus.CLOSED);
- }
- catch (SQLException exception) {
- this.setTransactionStatus(MSqlConnection.TransactionStatus.FAILED);
- throw new MSqlTransactionException("Could not roll back transaction.", exception);
- }
- }
-
- public MSqlConnection.TransactionStatus commitTransaction() throws MSqlTransactionException {
- switch (this.getTransactionStatus()) {
- case SUCCESSFUL:
- try {
- this.getConnection().commit();
- this.getConnection().setAutoCommit(true);
- this.setTransactionStatus(MSqlConnection.TransactionStatus.CLOSED);
- return MSqlConnection.TransactionStatus.SUCCESSFUL;
- }
- catch (SQLException exception) {
- this.rollBackTransaction();
- return MSqlConnection.TransactionStatus.FAILED;
- }
- case FAILED:
- this.rollBackTransaction();
- return MSqlConnection.TransactionStatus.FAILED;
- default: // instead of "case CLOSED:" (necessary to avoid Java compilation errors)
- throw new MSqlTransactionException("Transaction not started.");
- }
- }
-
- /* Statements. */
-
- public MSqlStatementResults executePreparedStatement(String statement) throws MSqlStatementException {
- return this.executePreparedStatement(statement, new LinkedList<Object>());
- }
-
- public MSqlStatementResults executePreparedStatement(String statement, LinkedList<Object> parameters) throws MSqlStatementException {
- if (MText.isBlank(statement)) {
- throw new IllegalArgumentException("Invalid 'statement': null or empty.");
- }
- if (null == parameters) {
- throw new IllegalArgumentException("Invalid 'parameters': null.");
- }
- //
- MSqlStatementResults results = null;
- PreparedStatement preparedStatement = null;
- try {
- // Prepare the statement.
- preparedStatement = this.getConnection().prepareStatement(statement, PreparedStatement.RETURN_GENERATED_KEYS);
- for (int p = 0; parameters.size() > p; p++) {
- preparedStatement.setObject(p + 1, parameters.get(p));
- }
- // Execute the statement and parse the results.
- preparedStatement.execute();
- results = new MSqlStatementResults(preparedStatement);
- }
- catch (SQLException exception) {
- if (MSqlConnection.TransactionStatus.SUCCESSFUL == this.getTransactionStatus()) {
- this.setTransactionStatus(MSqlConnection.TransactionStatus.FAILED);
- }
- throw new MSqlStatementException(String.format("Could not execute prepared statement: %s.", preparedStatement), exception);
- }
- return results;
- }
-
- /* Tables. */
-
- public MSqlTable getTable(String table, String primaryKey) {
- return new MSqlTable(this, table, primaryKey);
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-@SuppressWarnings("serial")
-public class MSqlConnectionFailureException extends MSqlException {
-
- /* */
-
- public MSqlConnectionFailureException() {
- super();
- }
-
- public MSqlConnectionFailureException(String message) {
- super(message);
- }
-
- public MSqlConnectionFailureException(Throwable error) {
- super(error);
- }
-
- public MSqlConnectionFailureException(String message, Throwable error) {
- super(message, error);
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-
-public class MSqlConnectionGenerator extends MObject {
-
- protected String driver = null;
- protected String url = null;
- protected String username = null;
- protected String password = null;
-
- /* */
-
- public MSqlConnectionGenerator(String driver, String url, String username, String password) {
- super();
- //
- if (MText.isBlank(driver)) {
- throw new IllegalArgumentException("Invalid 'driver': null or empty.");
- }
- if (MText.isBlank(url)) {
- throw new IllegalArgumentException("Invalid 'url': null or empty.");
- }
- if (null == username) {
- throw new IllegalArgumentException("Invalid 'username': null.");
- }
- if (null == password) {
- throw new IllegalArgumentException("Invalid 'password': null.");
- }
- //
- this.driver = driver;
- this.url = url;
- this.username = username;
- this.password = password;
- }
-
- /* Driver. */
-
- public String getDriver() {
- return this.driver;
- }
-
- /* Url. */
-
- public String getUrl() {
- return this.url;
- }
-
- /* Username. */
-
- public String getUsername() {
- return this.username;
- }
-
- /* Password. */
-
- public String getPassword() {
- return this.password;
- }
-
- /* Generator. */
-
- public MSqlConnection getNewSqlConnection() throws MSqlConnectionFailureException {
- return new MSqlConnection(this.getDriver(), this.getUrl(), this.getUsername(), this.getPassword());
- }
-
- public boolean isGeneratorFor(MSqlConnection sqlConnection) {
- if (null == sqlConnection) {
- throw new IllegalArgumentException("Invalid 'sqlConnection': null.");
- }
- //
- if (!sqlConnection.getDriver().equals(this.getDriver())) {
- return false;
- }
- if (!sqlConnection.getUrl().equals(this.getUrl())) {
- return false;
- }
- if (!sqlConnection.getUsername().equals(this.getUsername())) {
- return false;
- }
- if (!sqlConnection.getPassword().equals(this.getPassword())) {
- return false;
- }
- //
- return true;
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-import com.marcozanon.macaco.MObject;
-import java.util.LinkedList;
-
-public class MSqlConnectionPool extends MObject {
-
- protected MSqlConnectionGenerator sqlConnectionGenerator = null;
-
- protected int minimumSize = 0;
- protected int maximumSize = 0;
- protected LinkedList<MSqlConnection> sqlConnectionPool = new LinkedList<MSqlConnection>();
-
- /* */
-
- public MSqlConnectionPool(String driver, String url, String username, String password, int minimumSize, int maximumSize) throws MSqlConnectionFailureException {
- super();
- //
- if (0 > minimumSize) {
- throw new IllegalArgumentException(String.format("Invalid 'minimumSize': %s.", minimumSize));
- }
- if (1 > maximumSize) {
- throw new IllegalArgumentException(String.format("Invalid 'maximumSize': %s.", maximumSize));
- }
- else if (minimumSize > maximumSize) {
- throw new IllegalArgumentException(String.format("Invalid 'maximumSize': %s < %s ('minimumSize').", maximumSize, minimumSize));
- }
- //
- this.sqlConnectionGenerator = new MSqlConnectionGenerator(driver, url, username, password);
- this.minimumSize = minimumSize;
- this.maximumSize = maximumSize;
- //
- this.initializeSqlConnectionPool();
- }
-
- /* Sql connection generator. */
-
- protected MSqlConnectionGenerator getSqlConnectionGenerator() {
- return this.sqlConnectionGenerator;
- }
-
- /* Sql connection pool. */
-
- protected int getMinimumSize() {
- return this.minimumSize;
- }
-
- protected int getMaximumSize() {
- return this.maximumSize;
- }
-
- protected LinkedList<MSqlConnection> getSqlConnectionPool() {
- return this.sqlConnectionPool;
- }
-
- protected void initializeSqlConnectionPool() throws MSqlConnectionFailureException {
- for (int c = 0; c < this.getMinimumSize(); c++) {
- MSqlConnection sqlConnection = this.getSqlConnectionGenerator().getNewSqlConnection();
- this.getSqlConnectionPool().add(sqlConnection);
- }
- }
-
- public synchronized MSqlConnection popSqlConnection() throws MSqlConnectionFailureException {
- LinkedList<MSqlConnection> sqlConnectionPool = this.getSqlConnectionPool();
- MSqlConnection sqlConnection = sqlConnectionPool.removeLast();
- if (this.getMinimumSize() > sqlConnectionPool.size()) {
- sqlConnectionPool.add(this.getSqlConnectionGenerator().getNewSqlConnection());
- }
- return sqlConnection;
- }
-
- public synchronized void pushSqlConnection(MSqlConnection sqlConnection) throws MSqlConnectionFailureException {
- if (null == sqlConnection) {
- throw new IllegalArgumentException("Invalid 'sqlConnection': null.");
- }
- else if (!this.getSqlConnectionGenerator().isGeneratorFor(sqlConnection)) {
- throw new IllegalArgumentException("Invalid 'sqlConnection': not generated by this Sql connection generator.");
- }
- else if (sqlConnection.isClosed()) {
- throw new IllegalArgumentException("Invalid 'sqlConnection': closed.");
- }
- //
- LinkedList<MSqlConnection> sqlConnectionPool = this.getSqlConnectionPool();
- if (this.getMaximumSize() >= sqlConnectionPool.size()) {
- sqlConnectionPool.add(sqlConnection);
- }
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-import com.marcozanon.macaco.MException;
-
-public abstract class MSqlException extends MException {
-
- /* */
-
- public MSqlException() {
- super();
- }
-
- public MSqlException(String message) {
- super(message);
- }
-
- public MSqlException(Throwable error) {
- super(error);
- }
-
- public MSqlException(String message, Throwable error) {
- super(message, error);
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-@SuppressWarnings("serial")
-public class MSqlStatementException extends MSqlException {
-
- /* */
-
- public MSqlStatementException() {
- super();
- }
-
- public MSqlStatementException(String message) {
- super(message);
- }
-
- public MSqlStatementException(Throwable error) {
- super(error);
- }
-
- public MSqlStatementException(String message, Throwable error) {
- super(message, error);
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-
-public class MSqlStatementResults extends MObject {
-
- protected PreparedStatement preparedStatement = null;
- protected ResultSet resultSet = null;
-
- protected LinkedList<LinkedHashMap<String, Object>> records = new LinkedList<LinkedHashMap<String, Object>>();
-
- protected LinkedHashSet<Object> generatedKeys = new LinkedHashSet<Object>();
-
- /* */
-
- public MSqlStatementResults(PreparedStatement preparedStatement) throws MSqlStatementException {
- super();
- //
- if (null == preparedStatement) {
- throw new IllegalArgumentException("Invalid 'preparedStatement': null.");
- }
- //
- this.preparedStatement = preparedStatement;
- //
- try {
- this.resultSet = this.getPreparedStatement().getResultSet();
- if (null != this.getResultSet()) {
- while (this.getResultSet().next()) {
- ResultSetMetaData resultSetMetaData = this.getResultSet().getMetaData();
- LinkedHashMap<String, Object> record = new LinkedHashMap<String, Object>();
- for (int f = 0; resultSetMetaData.getColumnCount() > f; f++) {
- String field = resultSetMetaData.getColumnLabel(f + 1);
- record.put(field, this.getResultSet().getObject(field));
- }
- this.getRecords().add(record);
- }
- }
- }
- catch (SQLException exception) {
- throw new MSqlStatementException("Could not retrieve statement records.", exception);
- }
- //
- try {
- ResultSet generatedKeysResultSet = this.getPreparedStatement().getGeneratedKeys();
- while (generatedKeysResultSet.next()) {
- this.getGeneratedKeys().add(generatedKeysResultSet.getObject(1));
- }
- generatedKeysResultSet.close();
- }
- catch (SQLException exception) {
- throw new MSqlStatementException("Could not retrieve generated keys.", exception);
- }
- }
-
- public void close() throws MSqlConnectionFailureException {
- try {
- if (null != this.getResultSet()) {
- this.getResultSet().close();
- }
- this.getPreparedStatement().close();
- }
- catch (SQLException exception) {
- throw new MSqlConnectionFailureException("Could not close statement and/or result set references.", exception);
- }
- }
-
- protected void finalize() {
- try {
- this.close();
- }
- catch (Exception exception) {
- }
- }
-
- /* References. */
-
- protected PreparedStatement getPreparedStatement() {
- return this.preparedStatement;
- }
-
- public ResultSet getResultSet() {
- return this.resultSet;
- }
-
- /* Records. */
-
- public LinkedList<LinkedHashMap<String, Object>> getRecords() {
- return this.records;
- }
-
- public LinkedList<Object> getRecordsByField(String field) {
- if (MText.isBlank(field)) {
- throw new IllegalArgumentException("Invalid 'field': null or empty.");
- }
- //
- LinkedList<Object> recordsByField = new LinkedList<Object>();
- for (LinkedHashMap<String, Object> record: this.getRecords()) {
- Object r = record.get(field);
- if (null == r) {
- throw new IllegalArgumentException(String.format("Invalid 'field': %s.", field));
- }
- recordsByField.add(r);
- }
- return recordsByField;
- }
-
- /* Generated keys. */
-
- public LinkedHashSet<Object> getGeneratedKeys() {
- return this.generatedKeys;
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-import com.marcozanon.macaco.MObject;
-import com.marcozanon.macaco.text.MText;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-
-public class MSqlTable extends MObject {
-
- protected MSqlConnection sqlConnection = null;
- protected String table = null;
- protected String primaryKey = null;
-
- /* */
-
- public MSqlTable(MSqlConnection sqlConnection, String table, String primaryKey) {
- super();
- //
- if (null == sqlConnection) {
- throw new IllegalArgumentException("Invalid 'sqlConnection': null.");
- }
- if (MText.isBlank(table)) {
- throw new IllegalArgumentException("Invalid 'table': null or empty.");
- }
- if (MText.isBlank(primaryKey)) {
- throw new IllegalArgumentException("Invalid 'primaryKey': null or empty.");
- }
- //
- this.sqlConnection = sqlConnection;
- this.table = table;
- this.primaryKey = primaryKey;
- }
-
- /* Sql connection. */
-
- protected MSqlConnection getSqlConnection() {
- return this.sqlConnection;
- }
-
- /* Table. */
-
- public String getTable() {
- return this.table;
- }
-
- /* Primary key. */
-
- public String getPrimaryKey() {
- return this.primaryKey;
- }
-
- /* Statements. */
-
- protected MSqlStatementResults insertRecord(LinkedHashMap<String, Object> map) throws MSqlStatementException {
- if (null == map) {
- throw new IllegalArgumentException("Invalid 'map': null.");
- }
- //
- LinkedList<Object> p = new LinkedList<Object>();
- StringBuilder fields = new StringBuilder("");
- StringBuilder s = new StringBuilder("");
- for (String field: map.keySet()) {
- fields.append("\"" + this.getTable() + "\".\"" + field + "\", ");
- s.append("?, ");
- p.add(map.get(field));
- }
- fields.delete(fields.length() - 2, fields.length());
- s.delete(s.length() - 2, s.length());
- return this.getSqlConnection().executePreparedStatement(" INSERT INTO \"" + this.getTable() + "\""
- + " (" + fields + ")"
- + " VALUES (" + s + ")",
- p);
- }
-
- protected MSqlStatementResults updateRecord(LinkedHashMap<String, Object> map, Object id) throws MSqlStatementException {
- if (null == map) {
- throw new IllegalArgumentException("Invalid 'map': null.");
- }
- if (null == id) {
- throw new IllegalArgumentException("Invalid 'id': null.");
- }
- //
- LinkedList<Object> p = new LinkedList<Object>();
- StringBuilder s = new StringBuilder("");
- for (String field: map.keySet()) {
- s.append("\"" + this.getTable() + "\".\"" + field + "\" = ?, ");
- p.add(map.get(field));
- }
- s.delete(s.length() - 2, s.length());
- p.add(id);
- return this.getSqlConnection().executePreparedStatement(" UPDATE \"" + this.getTable() + "\""
- + " SET " + s
- + " WHERE (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)",
- p);
- }
-
- public MSqlStatementResults setRecord(LinkedHashMap<String, Object> map, Object id) throws MSqlStatementException {
- if (null == id) {
- return this.insertRecord(map);
- }
- else {
- return this.updateRecord(map, id);
- }
- }
-
- public MSqlStatementResults getRecord(Object id) throws MSqlStatementException {
- if (null == id) {
- throw new IllegalArgumentException("Invalid 'id': null.");
- }
- //
- LinkedList<Object> p = new LinkedList<Object>();
- p.add(id);
- return this.getSqlConnection().executePreparedStatement(" SELECT *"
- + " FROM \"" + this.getTable() + "\""
- + " WHERE (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)",
- p);
- }
-
- public MSqlStatementResults deleteRecord(Object id) throws MSqlStatementException {
- if (null == id) {
- throw new IllegalArgumentException("Invalid 'id': null.");
- }
- //
- LinkedList<Object> p = new LinkedList<Object>();
- p.add(id);
- return this.getSqlConnection().executePreparedStatement(" DELETE FROM \"" + this.getTable() + "\""
- + " WHERE (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)",
- p);
- }
-
- public MSqlStatementResults deleteRecords(LinkedHashSet idSet) throws MSqlStatementException {
- if (null == idSet) {
- throw new IllegalArgumentException("Invalid 'idSet': null.");
- }
- //
- StringBuilder whereClause = new StringBuilder("(0)");
- LinkedList<Object> p = new LinkedList<Object>();
- for (Object id: idSet) {
- whereClause.append(" OR (\"" + this.getTable() + "\".\"" + this.getPrimaryKey() + "\" = ?)");
- p.add(id);
- }
- return this.getSqlConnection().executePreparedStatement(" DELETE FROM \"" + this.getTable() + "\""
- + " WHERE (" + whereClause + ")",
- p);
- }
-
-}
+++ /dev/null
-/**
- * Macaco
- * Copyright (c) 2009-2015 Marco Zanon <info@marcozanon.com>.
- * Released under MIT license (see LICENSE for details).
- */
-
-package com.marcozanon.macaco.sql;
-
-@SuppressWarnings("serial")
-public class MSqlTransactionException extends MSqlException {
-
- /* */
-
- public MSqlTransactionException() {
- super();
- }
-
- public MSqlTransactionException(String message) {
- super(message);
- }
-
- public MSqlTransactionException(Throwable error) {
- super(error);
- }
-
- public MSqlTransactionException(String message, Throwable error) {
- super(message, error);
- }
-
-}