Renamed a package and the corresponding class names. Also styled the code a little.
authorMarco Zanon <info@marcozanon.com>
Thu, 29 Oct 2015 16:03:35 +0000 (16:03 +0000)
committerMarco Zanon <info@marcozanon.com>
Thu, 29 Oct 2015 16:03:35 +0000 (16:03 +0000)
19 files changed:
4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnection.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionFailureException.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionGenerator.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionPool.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MDatabaseException.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MSqlStatementException.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MSqlStatementResults.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MSqlTable.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/database/MSqlTransactionException.java [new file with mode: 0644]
4.x/src/java/com/marcozanon/macaco/logging/MLogDatabaseTable.java
4.x/src/java/com/marcozanon/macaco/sql/MSqlConnection.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionFailureException.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionGenerator.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionPool.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlException.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlStatementException.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlStatementResults.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlTable.java [deleted file]
4.x/src/java/com/marcozanon/macaco/sql/MSqlTransactionException.java [deleted file]

diff --git a/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnection.java b/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnection.java
new file mode 100644 (file)
index 0000000..63aa6ee
--- /dev/null
@@ -0,0 +1,246 @@
+/**
+ * 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);
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionFailureException.java b/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionFailureException.java
new file mode 100644 (file)
index 0000000..3092f1d
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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);
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionGenerator.java b/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionGenerator.java
new file mode 100644 (file)
index 0000000..76b62e0
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * 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;
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionPool.java b/4.x/src/java/com/marcozanon/macaco/database/MDatabaseConnectionPool.java
new file mode 100644 (file)
index 0000000..1b3b636
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * 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);
+        }
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MDatabaseException.java b/4.x/src/java/com/marcozanon/macaco/database/MDatabaseException.java
new file mode 100644 (file)
index 0000000..a6cce0e
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * 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);
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MSqlStatementException.java b/4.x/src/java/com/marcozanon/macaco/database/MSqlStatementException.java
new file mode 100644 (file)
index 0000000..dced93b
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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);
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MSqlStatementResults.java b/4.x/src/java/com/marcozanon/macaco/database/MSqlStatementResults.java
new file mode 100644 (file)
index 0000000..b89eff2
--- /dev/null
@@ -0,0 +1,128 @@
+/**
+ * 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;
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MSqlTable.java b/4.x/src/java/com/marcozanon/macaco/database/MSqlTable.java
new file mode 100644 (file)
index 0000000..f48524e
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * 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);
+    }
+
+}
diff --git a/4.x/src/java/com/marcozanon/macaco/database/MSqlTransactionException.java b/4.x/src/java/com/marcozanon/macaco/database/MSqlTransactionException.java
new file mode 100644 (file)
index 0000000..b19ae52
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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);
+    }
+
+}
index 7e032307857c31301d2e5bcf0186eaf60e30be6b..bfdb828360c2ce805ecc6692f5cc54f2e3109f32 100644 (file)
@@ -6,11 +6,11 @@
 
 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;
@@ -18,21 +18,21 @@ import java.util.LinkedHashMap;
 
 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.");
@@ -44,7 +44,7 @@ public class MLogDatabaseTable extends MLogTarget {
             throw new IllegalArgumentException("Invalid 'logDatabaseField': null or empty.");
         }
         //
-        this.sqlConnectionPool = sqlConnectionPool;
+        this.databaseConnectionPool = databaseConnectionPool;
         this.logDatabaseTable = logDatabaseTable;
         this.logDatabaseTablePrimaryKey = logDatabaseTablePrimaryKey;
         this.logDatabaseField = logDatabaseField;
@@ -53,10 +53,10 @@ public class MLogDatabaseTable extends MLogTarget {
     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. */
@@ -95,15 +95,15 @@ public class MLogDatabaseTable extends MLogTarget {
                 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) {
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnection.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnection.java
deleted file mode 100644 (file)
index 12ab736..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * 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);
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionFailureException.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionFailureException.java
deleted file mode 100644 (file)
index fd0636b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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);
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionGenerator.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionGenerator.java
deleted file mode 100644 (file)
index 1a98ddf..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * 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;
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionPool.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlConnectionPool.java
deleted file mode 100644 (file)
index 4523bfd..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * 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);
-        }
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlException.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlException.java
deleted file mode 100644 (file)
index 6309000..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * 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);
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlStatementException.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlStatementException.java
deleted file mode 100644 (file)
index 9cc7d6d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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);
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlStatementResults.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlStatementResults.java
deleted file mode 100644 (file)
index 7d3210a..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * 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;
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlTable.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlTable.java
deleted file mode 100644 (file)
index 932e776..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * 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);
-    }
-
-}
diff --git a/4.x/src/java/com/marcozanon/macaco/sql/MSqlTransactionException.java b/4.x/src/java/com/marcozanon/macaco/sql/MSqlTransactionException.java
deleted file mode 100644 (file)
index 62773e1..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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);
-    }
-
-}