Skip to content

Commit

Permalink
JDBC-226 / JDBC-252 : Workaround for read only tables in OpenOffice /…
Browse files Browse the repository at this point in the history
… LibreOffice Base when using roles to connect
  • Loading branch information
mrotteveel committed May 6, 2012
1 parent f963244 commit eb7c113
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 73 deletions.
86 changes: 47 additions & 39 deletions src/main/org/firebirdsql/jdbc/AbstractDatabaseMetaData.java
Expand Up @@ -3261,8 +3261,6 @@ else if (privilege.equals("M"))
return new FBResultSet(xsqlvars, rows);
}



private static final String GET_TABLE_PRIVILEGES_START = "select"
+ " null as TABLE_CAT, "
+ " null as TABLE_SCHEM,"
Expand Down Expand Up @@ -3316,6 +3314,40 @@ public ResultSet getTablePrivileges(String catalog, String schemaPattern,
checkCatalogAndSchema(catalog, schemaPattern);
tableNamePattern = stripQuotes(stripEscape(tableNamePattern), true);

XSQLVAR[] xsqlvars = buildTablePrivilegeRSMetaData();

Clause tableClause = new Clause("RDB$RELATION_NAME", tableNamePattern);

String sql = GET_TABLE_PRIVILEGES_START;
sql += tableClause.getCondition();
sql += GET_TABLE_PRIVILEGES_END;

// check the original case identifiers first
ArrayList params = new ArrayList();
if (!tableClause.getCondition().equals("")) {
params.add(tableClause.getOriginalCaseValue());
}

ResultSet rs = doQuery(sql, params);

// if nothing found, check the uppercased identifiers
if (!rs.next()) {
params.clear();
if (!tableClause.getCondition().equals("")) {
params.add(tableClause.getValue());
}

rs = doQuery(sql, params);

// if nothing found, return an empty result set
if (!rs.next())
return new FBResultSet(xsqlvars, new ArrayList());
}

return processTablePrivileges(xsqlvars, rs);
}

protected final XSQLVAR[] buildTablePrivilegeRSMetaData() {
XSQLVAR[] xsqlvars = new XSQLVAR[7];

xsqlvars[0] = new XSQLVAR();
Expand Down Expand Up @@ -3359,45 +3391,21 @@ public ResultSet getTablePrivileges(String catalog, String schemaPattern,
xsqlvars[6].sqllen = 31;
xsqlvars[6].sqlname = "IS_GRANTABLE";
xsqlvars[6].relname = "TABLEPRIV";

Clause tableClause = new Clause("RDB$RELATION_NAME", tableNamePattern);

String sql = GET_TABLE_PRIVILEGES_START;
sql += tableClause.getCondition();
sql += GET_TABLE_PRIVILEGES_END;

// check the original case identifiers first
ArrayList params = new ArrayList();
if (!tableClause.getCondition().equals("")) {
params.add(tableClause.getOriginalCaseValue());
}

return xsqlvars;
}

protected final FBResultSet processTablePrivileges(XSQLVAR[] xsqlvars, ResultSet fbTablePrivileges) throws SQLException {
ArrayList rows = new ArrayList();
ResultSet rs = doQuery(sql, params);

// if nothing found, check the uppercased identifiers
if (!rs.next()) {
params.clear();
if (!tableClause.getCondition().equals("")) {
params.add(tableClause.getValue());
}

rs = doQuery(sql, params);

// if nothing found, return an empty result set
if (!rs.next())
return new FBResultSet(xsqlvars, rows);

}

do {
byte[][] row = new byte[7][];
row[0] = null;
row[1] = null;
row[2] = getBytes(rs.getString("TABLE_NAME"));
row[3] = getBytes(rs.getString("GRANTOR"));
row[4] = getBytes(rs.getString("GRANTEE"));
String privilege = rs.getString("PRIVILEGE");
row[2] = getBytes(fbTablePrivileges.getString("TABLE_NAME"));
row[3] = getBytes(fbTablePrivileges.getString("GRANTOR"));
row[4] = getBytes(fbTablePrivileges.getString("GRANTEE"));
String privilege = fbTablePrivileges.getString("PRIVILEGE");
if (privilege.equals("A"))
row[5] = getBytes("ALL");
else if (privilege.equals("S"))
Expand All @@ -3409,17 +3417,17 @@ else if (privilege.equals("I"))
else if (privilege.equals("U"))
row[5] = getBytes("UPDATE");
else if (privilege.equals("R"))
row[5] = getBytes("REFERENCE");
row[5] = getBytes("REFERENCE"); // TODO: JDBC spec specifies REFRENCES (yes: typo and + S)
else if (privilege.equals("M"))
row[5] = getBytes("MEMBEROF");
int isGrantable = rs.getShort("IS_GRANTABLE");
int isGrantable = fbTablePrivileges.getShort("IS_GRANTABLE");
if (isGrantable==0)
row[6] = getBytes("NO");
else
row[6] = getBytes("YES");

rows.add(row);
} while (rs.next());
} while (fbTablePrivileges.next());

return new FBResultSet(xsqlvars, rows);
}
Expand Down Expand Up @@ -6154,14 +6162,14 @@ public String getViewSourceCode(String viewName) throws SQLException {
}


private void checkCatalogAndSchema(String catalog, String schema) throws SQLException {
protected void checkCatalogAndSchema(String catalog, String schema) throws SQLException {
/*
* we ignore incorrect catalog and schema specification as
* suggested by Thomas Kellerer in JDBC Forum
*/
}

private class Clause {
protected class Clause {
private String condition = "";
private String value;
private String originalCaseValue;
Expand Down
107 changes: 73 additions & 34 deletions src/openoffice/org/firebirdsql/jdbc/oo/OODatabaseMetaData.java
Expand Up @@ -185,13 +185,84 @@ public ResultSet getSuperTypes(String catalog, String schemaPattern,

return super.getSuperTypes(catalog, schemaPattern, tableNamePattern);
}

private static final String GET_TABLE_PRIVILEGES_START_1 =
"SELECT " +
"null as TABLE_CAT, " +
"null as TABLE_SCHEM, " +
"RDB$RELATION_NAME as TABLE_NAME, " +
"RDB$GRANTOR as GRANTOR, " +
"RDB$USER as GRANTEE, " +
"RDB$PRIVILEGE as PRIVILEGE, " +
"RDB$GRANT_OPTION as IS_GRANTABLE " +
"FROM RDB$USER_PRIVILEGES " +
"WHERE ";
private static final String GET_TABLE_PRIVILEGES_END_1 =
" CURRENT_USER IN (RDB$USER, RDB$GRANTOR) AND RDB$FIELD_NAME IS NULL AND RDB$OBJECT_TYPE = 0";
private static final String GET_TABLE_PRIVILEGES_START_2 =
"UNION " +
"SELECT " +
"null as TABLE_CAT, " +
"null as TABLE_SCHEM, " +
"RDB$RELATION_NAME as TABLE_NAME, " +
"RDB$GRANTOR as GRANTOR, " +
"CURRENT_USER as GRANTEE, " +
"RDB$PRIVILEGE as PRIVILEGE, " +
"RDB$GRANT_OPTION as IS_GRANTABLE " +
"FROM RDB$USER_PRIVILEGES " +
"WHERE ";
private static final String GET_TABLE_PRIVILEGES_END_2 =
" RDB$USER = CURRENT_ROLE AND RDB$FIELD_NAME IS NULL AND RDB$OBJECT_TYPE = 0 " +
"ORDER BY 3, 6";

public ResultSet getTablePrivileges(String catalog, String schemaPattern,
String tableNamePattern) throws SQLException {
if (DEFAULT_SCHEMA.equals(schemaPattern)) schemaPattern = null;

return super.getTablePrivileges(catalog, schemaPattern,
tableNamePattern);
checkCatalogAndSchema(catalog, schemaPattern);
tableNamePattern = stripQuotes(stripEscape(tableNamePattern), true);

XSQLVAR[] xsqlvars = buildTablePrivilegeRSMetaData();

Clause tableClause1 = new Clause("RDB$RELATION_NAME", tableNamePattern);
Clause tableClause2 = new Clause("RDB$RELATION_NAME", tableNamePattern);

String sql = GET_TABLE_PRIVILEGES_START_1;
sql += tableClause1.getCondition();
sql += GET_TABLE_PRIVILEGES_END_1;
sql += GET_TABLE_PRIVILEGES_START_2;
sql += tableClause2.getCondition();
sql += GET_TABLE_PRIVILEGES_END_2;

// check the original case identifiers first
ArrayList params = new ArrayList();
if (!tableClause1.getCondition().equals("")) {
params.add(tableClause1.getOriginalCaseValue());
}
if (!tableClause2.getCondition().equals("")) {
params.add(tableClause2.getOriginalCaseValue());
}

ResultSet rs = doQuery(sql, params);

// if nothing found, check the uppercased identifiers
if (!rs.next()) {
params.clear();
if (!tableClause1.getCondition().equals("")) {
params.add(tableClause1.getValue());
}
if (!tableClause2.getCondition().equals("")) {
params.add(tableClause2.getValue());
}

rs = doQuery(sql, params);

// if nothing found, return an empty result set
if (!rs.next())
return new FBResultSet(xsqlvars, new ArrayList());
}

return processTablePrivileges(xsqlvars, rs);
}

public String stripEscape(String pattern) {
Expand All @@ -206,36 +277,4 @@ public String stripQuotes(String pattern) {
return pattern;
}
}

private class Clause {

private String condition = "";

private String value;

public Clause(String columnName, String pattern) {
if (pattern == null) {
return;
} else if (isAllCondition(pattern)) {
// do nothing to tableCondition
return;
} else if (hasNoWildcards(pattern)) {
value = stripQuotes(stripEscape(pattern));
condition = columnName + " = ? and ";
} else {
value = stripQuotes(pattern) + SPACES + "%";
condition = columnName + " || '" + SPACES
+ "' like ? escape '\\' and ";
}
}

public String getCondition() {
return condition;
}

public String getValue() {
return value;
}
}

}

0 comments on commit eb7c113

Please sign in to comment.