&& forrowsM.group(1).length() > 0)
? forrowsM.group(1).trim().split("\\s+") : null;
String[] origVals = (vars == null) ? null : new String[vars.length];
if (origVals != null) for (int i = 0; i < vars.length; i++)
origVals[i] = shared.userVars.get(vars[i]);
TokenList dupNesteds = token.nestedBlock.dup();
if (dupNesteds.size() < 2)
// TODO: Define message
throw new BadSpecial("Empty forrows loop");
Token queryToken = dupNesteds.remove(0);
if (queryToken.type != Token.SQL_TYPE)
// TODO: Define message
throw new BadSpecial("*forrows command not followed "
+ "immediately by an SQL statement");
setBuf(queryToken);
List<String[]> rowData = new ArrayList<String[]>();
ResultSet rs = null;
int colCount = 0;
Statement statement = processSQL();
if (statement == null)
// TODO: Define message
throw new BadSpecial("Failed to prepare SQL for loop");
try {
rs = statement.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
colCount = rsmd.getColumnCount();
if (vars != null && vars.length > colCount)
// TODO: Define message
throw new BadSpecial("*forrows command specifies "
+ vars.length
+ " variables, but query pulled only "
+ colCount + " columns");
if (colCount < 1) return;
String[] rowCells;
while (rs.next()) {
rowCells = new String[colCount];
rowData.add(rowCells);
for (int i = 1; i <= colCount; i++)
rowCells[i-1] = rs.getString(i);
}
} finally {
try {
if (rs != null) rs.close();
} catch (SQLException nse) {
// Purposefully doing nothing
} finally {
rs = null;
}
try {
statement.close();
} catch (SQLException nse) {
// Purposefully doing nothing
} finally {
statement = null;
}
}
lastSqlStatement = null;
// Done with SQL
if (rowData.size() > 0) {
String firstVal = rowData.get(0)[0];
String lastVal = rowData.get(rowData.size()-1)[colCount - 1];
shared.userVars.put("?",
(lastVal == null) ? nullRepToken : lastVal);
if (fetchingVar != null) {
if (firstVal == null)
shared.userVars.remove(fetchingVar);
else
shared.userVars.put(fetchingVar, firstVal);
updateUserSettings();
sqlExpandMode = null;
fetchingVar = null;
}
} else {
shared.userVars.put("?", "");
}
StringBuilder rowBuilder = new StringBuilder();
String rowVal;
try {
for (String[] cells : rowData) {
if (cells.length == 1) {
rowVal = (cells[0] == null) ? nullRepToken : cells[0];
} else {
rowBuilder.setLength(0);
for (String s : cells) {
if (rowBuilder.length() > 0)
rowBuilder.append(dsvColDelim);
rowBuilder.append((s == null) ? nullRepToken : s);
}
rowVal = rowBuilder.toString();
}
shared.userVars.put("*ROW", rowVal);
if (vars != null) for (int i = 0; i < vars.length; i++)
if (cells[i] == null)
shared.userVars.remove(vars[i]);
else
shared.userVars.put(vars[i], cells[i]);
updateUserSettings();
Recursion origRecursed = recursed;
recursed = Recursion.FORROWS;
try {
scanpass(dupNesteds.dup());
} catch (ContinueException ce) {
String ceMessage = ce.getMessage();
if (ceMessage != null
&& !ceMessage.equals("forrows")) throw ce;