/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.h2.bnf.Bnf;
import org.h2.bnf.context.DbContents;
import org.h2.bnf.context.DbContextRule;
import org.h2.bnf.context.DbProcedure;
import org.h2.bnf.context.DbSchema;
import org.h2.test.TestBase;
/**
* Test Bnf Sql parser
* @author Nicolas Fortin
*/
public class TestBnf extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
deleteDb("bnf");
try (Connection conn = getConnection("bnf")) {
testModes(conn);
testProcedures(conn, false);
}
try (Connection conn = getConnection("bnf;mode=mysql")) {
testProcedures(conn, true);
}
}
private void testModes(Connection conn) throws Exception {
DbContents dbContents;
dbContents = new DbContents();
dbContents.readContents("jdbc:h2:test", conn);
assertTrue(dbContents.isH2());
dbContents = new DbContents();
dbContents.readContents("jdbc:derby:test", conn);
assertTrue(dbContents.isDerby());
dbContents = new DbContents();
dbContents.readContents("jdbc:firebirdsql:test", conn);
assertTrue(dbContents.isFirebird());
dbContents = new DbContents();
dbContents.readContents("jdbc:sqlserver:test", conn);
assertTrue(dbContents.isMSSQLServer());
dbContents = new DbContents();
dbContents.readContents("jdbc:mysql:test", conn);
assertTrue(dbContents.isMySQL());
dbContents = new DbContents();
dbContents.readContents("jdbc:oracle:test", conn);
assertTrue(dbContents.isOracle());
dbContents = new DbContents();
dbContents.readContents("jdbc:postgresql:test", conn);
assertTrue(dbContents.isPostgreSQL());
dbContents = new DbContents();
dbContents.readContents("jdbc:sqlite:test", conn);
assertTrue(dbContents.isSQLite());
}
private void testProcedures(Connection conn, boolean isMySQLMode)
throws Exception {
// Register a procedure and check if it is present in DbContents
conn.createStatement().execute(
"DROP ALIAS IF EXISTS CUSTOM_PRINT");
conn.createStatement().execute(
"CREATE ALIAS CUSTOM_PRINT " +
"AS $$ void print(String s) { System.out.println(s); } $$");
conn.createStatement().execute(
"DROP TABLE IF EXISTS " +
"TABLE_WITH_STRING_FIELD");
conn.createStatement().execute(
"CREATE TABLE " +
"TABLE_WITH_STRING_FIELD (STRING_FIELD VARCHAR(50), INT_FIELD integer)");
DbContents dbContents = new DbContents();
dbContents.readContents("jdbc:h2:test", conn);
assertTrue(dbContents.isH2());
assertFalse(dbContents.isDerby());
assertFalse(dbContents.isFirebird());
assertEquals(null, dbContents.quoteIdentifier(null));
if (isMySQLMode) {
assertTrue(dbContents.isH2ModeMySQL());
assertEquals("TEST", dbContents.quoteIdentifier("TEST"));
assertEquals("TEST", dbContents.quoteIdentifier("Test"));
assertEquals("TEST", dbContents.quoteIdentifier("test"));
} else {
assertFalse(dbContents.isH2ModeMySQL());
assertEquals("TEST", dbContents.quoteIdentifier("TEST"));
assertEquals("\"Test\"", dbContents.quoteIdentifier("Test"));
assertEquals("\"test\"", dbContents.quoteIdentifier("test"));
}
assertFalse(dbContents.isMSSQLServer());
assertFalse(dbContents.isMySQL());
assertFalse(dbContents.isOracle());
assertFalse(dbContents.isPostgreSQL());
assertFalse(dbContents.isSQLite());
DbSchema defaultSchema = dbContents.getDefaultSchema();
DbProcedure[] procedures = defaultSchema.getProcedures();
Set<String> procedureName = new HashSet<String>(procedures.length);
for (DbProcedure procedure : procedures) {
assertTrue(defaultSchema == procedure.getSchema());
procedureName.add(procedure.getName());
}
if (isMySQLMode) {
assertTrue(procedureName.contains("custom_print"));
} else {
assertTrue(procedureName.contains("CUSTOM_PRINT"));
}
if (isMySQLMode) {
return;
}
// Test completion
Bnf bnf = Bnf.getInstance(null);
DbContextRule columnRule = new
DbContextRule(dbContents, DbContextRule.COLUMN);
bnf.updateTopic("column_name", columnRule);
bnf.updateTopic("user_defined_function_name", new
DbContextRule(dbContents, DbContextRule.PROCEDURE));
bnf.linkStatements();
// Test partial
Map<String, String> tokens;
tokens = bnf.getNextTokenList("SELECT CUSTOM_PR");
assertTrue(tokens.values().contains("INT"));
// Test identifiers are working
tokens = bnf.getNextTokenList("create table \"test\" as s" + "el");
assertTrue(tokens.values().contains("E" + "CT"));
tokens = bnf.getNextTokenList("create table test as s" + "el");
assertTrue(tokens.values().contains("E" + "CT"));
// Test || with and without spaces
tokens = bnf.getNextTokenList("select 1||f");
assertFalse(tokens.values().contains("R" + "OM"));
tokens = bnf.getNextTokenList("select 1 || f");
assertFalse(tokens.values().contains("R" + "OM"));
tokens = bnf.getNextTokenList("select 1 || 2 ");
assertTrue(tokens.values().contains("FROM"));
tokens = bnf.getNextTokenList("select 1||2");
assertTrue(tokens.values().contains("FROM"));
tokens = bnf.getNextTokenList("select 1 || 2");
assertTrue(tokens.values().contains("FROM"));
// Test keyword
tokens = bnf.getNextTokenList("SELECT LE" + "AS");
assertTrue(tokens.values().contains("T"));
// Test parameters
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT(");
assertTrue(tokens.values().contains("STRING_FIELD"));
assertFalse(tokens.values().contains("INT_FIELD"));
// Test parameters with spaces
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT ( ");
assertTrue(tokens.values().contains("STRING_FIELD"));
assertFalse(tokens.values().contains("INT_FIELD"));
// Test parameters with close bracket
tokens = bnf.getNextTokenList("SELECT CUSTOM_PRINT ( STRING_FIELD");
assertTrue(tokens.values().contains(")"));
}
}