Added query result equality algorithm.
This commit is contained in:
parent
305ea4211c
commit
9efc91f82f
|
@ -121,7 +121,7 @@ public class DatabaseHelper {
|
|||
// A result set is expected.
|
||||
window.appendOutput("Executing query:\n" + query);
|
||||
|
||||
QueryAction action = new QueryAction(statement.executeQuery(query));
|
||||
QueryAction action = new QueryAction(statement.executeQuery(query), isQueryOrdered(query));
|
||||
window.appendOutput(action.toString());
|
||||
return action;
|
||||
} else {
|
||||
|
@ -162,4 +162,13 @@ public class DatabaseHelper {
|
|||
return upper.startsWith("SELECT");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a query is ordered by something.
|
||||
* @param query The query to check.
|
||||
* @return True if the query makes use of the 'ORDER BY' clause.
|
||||
*/
|
||||
private static boolean isQueryOrdered(String query) {
|
||||
return query.toUpperCase().contains("ORDER BY");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<component id="c2e9b" class="javax.swing.JTextArea" binding="templateTextArea">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="select * from primes;"/>
|
||||
<text value="select id, value, other_value from primes;"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
|
@ -89,7 +89,7 @@
|
|||
<component id="17867" class="javax.swing.JTextArea" binding="testingTextArea">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="select * from primes;"/>
|
||||
<text value="select value, other_value, id from primes;"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
|
@ -356,7 +356,7 @@
|
|||
<component id="cc50b" class="javax.swing.JTextArea" binding="initializationTextArea">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="CREATE TABLE primes ( 	id SERIAL NOT NULL, 	value INT NOT NULL ); INSERT INTO primes(value) VALUES (2), (3), (5), (7), (11);" noi18n="true"/>
|
||||
<text value="CREATE TABLE primes ( 	id SERIAL NOT NULL, 	value INT NOT NULL, 	other_value TEXT NOT NULL DEFAULT 'fuck' ); INSERT INTO primes(value, other_value) VALUES (2, 'nigger'), (3, 'cunt'), (5, 'piss'), (7, 'shit'), (11, 'spic');" noi18n="true"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
|
|
|
@ -42,6 +42,9 @@ public class ExecutionLog {
|
|||
ExecutionAction theirAction = otherLogActions.get(i);
|
||||
System.out.println("My action: " + myAction + "\nTheir action: " + theirAction);
|
||||
System.out.println("\tEqual? " + myAction.equals(theirAction));
|
||||
if (!myAction.equals(theirAction)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -3,6 +3,8 @@ package nl.andrewlalis.log;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An action in which a query result set is returned. Note that SCROLL_INSENSITIVE statements must be used, otherwise
|
||||
|
@ -11,9 +13,11 @@ import java.sql.SQLException;
|
|||
public class QueryAction extends ExecutionAction {
|
||||
|
||||
private ResultSet resultSet;
|
||||
private boolean isOrdered;
|
||||
|
||||
public QueryAction(ResultSet resultSet) {
|
||||
public QueryAction(ResultSet resultSet, boolean isOrdered) {
|
||||
this.resultSet = resultSet;
|
||||
this.isOrdered = isOrdered;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,9 +35,124 @@ public class QueryAction extends ExecutionAction {
|
|||
|
||||
QueryAction otherAction = (QueryAction) other;
|
||||
|
||||
return true;
|
||||
try {
|
||||
ResultSetMetaData myMetaData = this.resultSet.getMetaData();
|
||||
ResultSetMetaData theirMetaData = otherAction.resultSet.getMetaData();
|
||||
|
||||
if (myMetaData.getColumnCount() != theirMetaData.getColumnCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int columnCount = myMetaData.getColumnCount();
|
||||
|
||||
List<Integer> myColumnsQueue = new ArrayList<>(columnCount);
|
||||
List<Integer> theirColumnsQueue = new ArrayList<>(columnCount);
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
myColumnsQueue.add(i);
|
||||
theirColumnsQueue.add(i);
|
||||
}
|
||||
|
||||
while (!myColumnsQueue.isEmpty()) {
|
||||
|
||||
System.out.println(myColumnsQueue);
|
||||
System.out.println(theirColumnsQueue);
|
||||
|
||||
// Pop the first column value.
|
||||
int myColumn = myColumnsQueue.remove(0);
|
||||
System.out.println("Testing my column " + myColumn);
|
||||
|
||||
// Find a column in their columns which has the same type as this one.
|
||||
boolean columnMatchFound = false;
|
||||
int failedAttempts = 0;
|
||||
while (!theirColumnsQueue.isEmpty() && failedAttempts < myColumnsQueue.size() + 1) {
|
||||
int theirColumn = theirColumnsQueue.remove(0);
|
||||
System.out.println("\tWith their column " + theirColumn);
|
||||
// Check if this column is of a compatible type.
|
||||
if (myMetaData.getColumnType(myColumn) == theirMetaData.getColumnType(theirColumn)) {
|
||||
System.out.println("\t\t+ Column type matches.");
|
||||
// Now check if the data inside is a match.
|
||||
List<String> myValues = new ArrayList<>();
|
||||
List<String> theirValues = new ArrayList<>();
|
||||
this.resultSet.beforeFirst();
|
||||
otherAction.resultSet.beforeFirst();
|
||||
|
||||
// Iterate until one of the result sets goes past the last row.
|
||||
while (true) {
|
||||
this.resultSet.next();
|
||||
otherAction.resultSet.next();
|
||||
if (this.resultSet.isAfterLast() || otherAction.resultSet.isAfterLast()) {
|
||||
break;
|
||||
}
|
||||
// Collect this row's values for both my column and their column.
|
||||
myValues.add(this.resultSet.getString(myColumn));
|
||||
theirValues.add(otherAction.resultSet.getString(theirColumn));
|
||||
}
|
||||
// Check if both row counts are the same; i.e. both reach the end at the same time.
|
||||
if (this.resultSet.isAfterLast() != otherAction.resultSet.isAfterLast()) {
|
||||
System.out.println("\t\t- Result sets have differing row counts!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare the values until an error.
|
||||
boolean isMatch = true;
|
||||
int index = 0;
|
||||
for (String value : myValues) {
|
||||
// If either query action is ordered, then require this.
|
||||
if (this.isOrdered || otherAction.isOrdered) {
|
||||
if (!(myValues.get(index).equals(theirValues.get(index)))) {
|
||||
System.out.println("\t\t- Their column (" + theirColumn + ") does not contain my column's (" + myColumn + ") value of " + value);
|
||||
isMatch = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!theirValues.contains(value)) {
|
||||
System.out.println("\t\t- Their column (" + theirColumn + ") does not contain my column's (" + myColumn + ") value of " + value);
|
||||
isMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
// If the column data matches.
|
||||
if (isMatch) {
|
||||
System.out.println("\t\t+ Columns Match! Ensuring my column " + myColumn +" and their column " + theirColumn + " are not added back to the queues.");
|
||||
// Leave the loop knowing we found a column, without adding it back.
|
||||
columnMatchFound = true;
|
||||
break;
|
||||
} else {
|
||||
System.out.println("\t\t- Columns do not match.");
|
||||
// No column was found to match, so add it back to their queue.
|
||||
theirColumnsQueue.add(theirColumn);
|
||||
failedAttempts++;
|
||||
}
|
||||
} else {
|
||||
System.out.println("\t\t- Column types do not match.");
|
||||
theirColumnsQueue.add(theirColumn);
|
||||
failedAttempts++;
|
||||
}
|
||||
}
|
||||
|
||||
// columnMatchFound == true when a column match has been found somewhere in other result set.
|
||||
if (!columnMatchFound) {
|
||||
System.out.println("\t\t- Could not find a matching column for my column " + myColumn);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we manage to get to the end without failing, return true.
|
||||
return true;
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the result set into a listing of column names and queries.
|
||||
* @return The string representation of this QueryAction.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue