public void logResultSet(ResultSet rs, List<Column> columns) throws SQLException { List<String> res = new LinkedList<>(); int i = 0; for (Column column : columns) { i++; Serializable v = column.getFromResultSet(rs, i); res.add(column.getKey() + "=" + loggedValue(v)); } log(" -> " + String.join(", ", res)); }
@Override public String getMatchMixinType(Column mixinsColumn, String mixin, boolean positive, String[] returnParam) { returnParam[0] = mixin; String sql = "ARRAY[?]::varchar[] <@ " + mixinsColumn.getFullQuotedName(); return positive ? sql : "NOT(" + sql + ")"; }
public String checkJdbcType(int actual, String actualName, int actualSize) { int expected = jdbcType; if (actual == expected) { return null; } if (dialect.isAllowedConversion(expected, actual, actualName, actualSize)) { return null; } return String.format("SQL type mismatch for %s: expected %s, database has %s / %s(%s)", getFullQuotedName(), getJDBCTypeName(expected), getJDBCTypeName(actual), actualName, actualSize); }
private Object getFieldValue(ResultSet rs, Column column) { try { int index = rs.findColumn(column.getPhysicalName()); return column.getFromResultSet(rs, index); } catch (SQLException e) { throw new DirectoryException("getFieldValue failed", e); } }
@Override public FulltextMatchInfo getFulltextScoredMatchInfo(String fulltextQuery, String indexName, int nthMatch, Column mainColumn, Model model, Database database) { String nthSuffix = nthMatch == 1 ? "" : String.valueOf(nthMatch); String indexSuffix = model.getFulltextIndexSuffix(indexName); Table ft = database.getTable(Model.FULLTEXT_TABLE_NAME); Column ftMain = ft.getColumn(Model.MAIN_KEY); Column stColumn = ft.getColumn(Model.FULLTEXT_SIMPLETEXT_KEY + indexSuffix); Column btColumn = ft.getColumn(Model.FULLTEXT_BINARYTEXT_KEY + indexSuffix); String match = String.format("MATCH (%s, %s)", stColumn.getFullQuotedName(), btColumn.getFullQuotedName()); FulltextMatchInfo info = new FulltextMatchInfo(); if (nthMatch == 1) { // Need only one JOIN involving the fulltext table info.joins = Collections.singletonList(new Join(Join.INNER, ft.getQuotedName(), null, null, ftMain.getFullQuotedName(), mainColumn.getFullQuotedName())); } info.whereExpr = String.format("%s AGAINST (? IN BOOLEAN MODE)", match); info.whereExprParam = fulltextQuery; // Note: using the boolean query in non-boolean mode gives approximate // results but it's the best we have as MySQL does not provide a score // in boolean mode. // Note: dividing by 10 is arbitrary, but MySQL cannot really // normalize scores. info.scoreExpr = String.format("(%s AGAINST (?) / 10)", match); info.scoreExprParam = fulltextQuery; info.scoreAlias = "_nxscore" + nthSuffix; info.scoreCol = new Column(mainColumn.getTable(), null, ColumnType.DOUBLE, null); return info; }
protected void postAddColumn(Column column, List<String> sqls, Model model) { if (column.isPrimary() && !(column.isIdentity() && dialect.isIdentityAlreadyPrimary())) { StringBuilder buf = new StringBuilder(); String constraintName = dialect.openQuote() + dialect.getPrimaryKeyConstraintName(key) buf.append(dialect.getAddPrimaryKeyConstraintString(constraintName)); buf.append('('); buf.append(column.getQuotedName()); buf.append(')'); sqls.add(buf.toString()); if (column.isIdentity()) { Table ft = column.getForeignTable(); if (ft != null) { Column fc = ft.getColumn(column.getForeignKey()); String constraintName = dialect.openQuote() + dialect.getForeignKeyConstraintName(key, column.getPhysicalName(), ft.getPhysicalName()) + dialect.closeQuote(); StringBuilder buf = new StringBuilder(); buf.append(getQuotedName()); buf.append(dialect.getAddForeignKeyConstraintString(constraintName, new String[] { column.getQuotedName() }, ft.getQuotedName(), new String[] { fc.getQuotedName() }, true)); if (dialect.supportsCircularCascadeDeleteConstraints() || (Model.MAIN_KEY.equals(fc.getPhysicalName()) && Model.MAIN_KEY.equals(column.getPhysicalName()))) { String columnName = column.getKey();
@Override public void visitFunction(Function node) { String func = node.name.toUpperCase(); Reference ref = (Reference) node.args.get(0); ref.accept(this); // whatColumns / whatKeys for column // replace column info with aggregate Column col = whatColumns.removeLast(); String key = whatKeys.removeLast(); final String aggFQN = func + "(" + col.getFullQuotedName() + ")"; final ColumnType aggType = getAggregateType(func, col.getType()); final int aggJdbcType = dialect.getJDBCTypeAndString(aggType).jdbcType; Column cc = new Column(col, col.getTable()) { private static final long serialVersionUID = 1L; @Override public String getFullQuotedName() { return aggFQN; } @Override public ColumnType getType() { return aggType; } @Override public int getJdbcType() { return aggJdbcType; } }; whatColumns.add(cc); whatKeys.add(func + "(" + key + ")"); }
/** * Alternative to {@link #setNewValues} * * @param columns the columns * @param deltas which of the columns are delta updates */ public void setUpdatedColumns(List<Column> columns, Set<String> deltas) { List<String> updatedColumns = new LinkedList<>(); for (Column column : columns) { if (column.isIdentity()) { // identity column is never inserted continue; } String col = column.getQuotedName(); String fvs = column.getFreeVariableSetter(); String update; if (deltas.contains(column.getKey())) { update = col + " = " + col + " + " + fvs; } else { update = col + " = " + fvs; } updatedColumns.add(update); } newValues = StringUtils.join(updatedColumns, ", "); }
@Override public FulltextMatchInfo getFulltextScoredMatchInfo(String fulltextQuery, String indexName, int nthMatch, Column mainColumn, Model model, Database database) { // TODO multiple indexes Table ft = database.getTable(model.FULLTEXT_TABLE_NAME); Column ftMain = ft.getColumn(model.MAIN_KEY); Column ftColumn = ft.getColumn(model.FULLTEXT_FULLTEXT_KEY); String nthSuffix = nthMatch == 1 ? "" : String.valueOf(nthMatch); String ftColumnName = ftColumn.getFullQuotedName(); if (ftColumn.getJdbcType() == Types.CLOB) { String colFmt = getClobCast(false); if (colFmt != null) { ftColumnName = String.format(colFmt, ftColumnName, Integer.valueOf(255)); } } FulltextMatchInfo info = new FulltextMatchInfo(); info.joins = new ArrayList<Join>(1); if (nthMatch == 1) { // Need only one JOIN involving the fulltext table info.joins.add(new Join(Join.INNER, ft.getQuotedName(), null, null, ftMain.getFullQuotedName(), mainColumn.getFullQuotedName())); } info.whereExpr = String.format("NX_CONTAINS(%s, ?) = 1", ftColumnName); info.whereExprParam = fulltextQuery; info.scoreExpr = "1"; info.scoreAlias = "NXSCORE" + nthSuffix; info.scoreCol = new Column(mainColumn.getTable(), null, ColumnType.DOUBLE, null); return info; }
Insert insert = new Insert(table); for (Column column : columns) { if (column.isIdentity()) { String quotedName = column.getQuotedName(); String key = column.getKey(); if (key.equals(Model.MAIN_KEY) // select.setFrom(table.getQuotedName()); select.setWhat(String.join(", ", selectWhats)); select.setWhere(whereColumn.getQuotedName() + " = ?"); insert.setValues(select.getStatement()); String sql = insert.getStatement();
protected void visitScore() { if (inSelect) { Column col = new Column(hierTable, null, ColumnType.DOUBLE, null); whatColumns.add(col); whatKeys.add(NXQL.ECM_FULLTEXT_SCORE); } else { buf.append(aliasesByName.get(NXQL.ECM_FULLTEXT_SCORE)); } }
protected void visitReference(Column column, String cast, int arrayElementIndex) { if (DATE_CAST.equals(cast) && column.getType() != ColumnType.TIMESTAMP) { throw new QueryParseException("Cannot cast to " + cast + ": " + column); } String qname = column.getFullQuotedName(); if (arrayElementIndex != -1) { if (column.isArray()) { qname = dialect.getArrayElementString(qname, arrayElementIndex); } else { throw new QueryParseException( "Cannot use array index " + arrayElementIndex + " for non-array column " + column); } } // some databases (Derby) can't do comparisons on CLOB if (column.getJdbcType() == Types.CLOB) { String colFmt = dialect.getClobCast(inOrderBy); if (colFmt != null) { qname = String.format(colFmt, qname, Integer.valueOf(255)); } } if (cast != null) { // only DATE cast for now String fmt = dialect.getDateCast(); buf.append(String.format(fmt, qname)); } else { buf.append(qname); } }
protected void postProcessDelete() { Delete delete = new Delete(table); String wheres = table.getColumns() .stream() .filter(col -> Model.MAIN_KEY.equals(col.getKey())) .map(col -> col.getQuotedName() + " = ?") .collect(Collectors.joining(" AND ")); delete.setWhere(wheres); deleteSqlMap.put(tableName, delete.getStatement()); }
protected String getArrayOpSql(Column arrayColumn, String refName, boolean positive, Table dataHierTable, String op) { Table table = arrayColumn.getTable(); String tableAliasName = openQuote() + getTableName(refName) + closeQuote(); String sql = String.format("EXISTS (SELECT 1 FROM %s AS %s WHERE %s = %s AND %s %s ?)", getArraySubQuery(arrayColumn, tableAliasName).toSql(), tableAliasName, dataHierTable.getColumn(Model.MAIN_KEY).getFullQuotedName(), tableAliasName + '.' + table.getColumn(Model.MAIN_KEY).getQuotedName(), tableAliasName + '.' + Model.COLL_TABLE_VALUE_KEY, op); if (!positive) { sql = "NOT(" + sql + ")"; } return sql; }
protected void getTable(Connection connection, String tbl) throws SQLException { String tablePhysicalName = dialect.getTableName(tbl); table = new TableImpl(dialect, tablePhysicalName, tablePhysicalName); keyCol = addColumn(KEY_COL, ColumnType.SYSNAME); keyCol.setPrimary(true); keyCol.setNullable(false); longCol = addColumn(LONG_COL, ColumnType.LONG); stringCol = addColumn(STRING_COL, ColumnType.CLOB); bytesCol = addColumn(BYTES_COL, ColumnType.BLOB); ttlCol = addColumn(TTL_COL, ColumnType.LONG); table.addIndex(TTL_COL); tableName = table.getQuotedName(); keyColName = keyCol.getQuotedName(); longColName = longCol.getQuotedName(); stringColName = stringCol.getQuotedName(); bytesColName = bytesCol.getQuotedName(); ttlColName = ttlCol.getQuotedName(); if (!tableExists(connection)) { createTable(connection); } checkColumns(connection); }
protected void postProcessRootIdSelect() { String what = null; String where = null; for (Column column : table.getColumns()) { String key = column.getKey(); String qname = column.getQuotedName(); if (key.equals(Model.MAIN_KEY)) { what = qname; selectRootIdWhatColumn = column; } else if (key.equals(Model.REPOINFO_REPONAME_KEY)) { where = qname + " = ?"; } else { throw new RuntimeException(column.toString()); } } Select select = new Select(table); select.setWhat(what); select.setFrom(table.getQuotedName()); select.setWhere(where); selectRootIdSql = select.getStatement(); }
/** * Gets the SQL to use to refer to a column in an expression. * <p> * Needed for Oracle CLOB. * * @param column the column used in an expression * @return the SQL to use to refer to it * * @since 10.10 */ public String getQuotedNameForExpression(Column column) { return column.getQuotedName(); }
List<Column> opaqueColumns = new LinkedList<>(); for (Column column : table.getColumns()) { if (column.isOpaque()) { opaqueColumns.add(column); } else if (skipColumns == null || !skipColumns.contains(column.getKey())) { whatColumns.add(column); whats.add(column.getQuotedName()); StringBuilder wherebuf = new StringBuilder(whereColumn.getQuotedName()); wherebuf.append(" IN ("); for (int i = 0; i < nids; i++) { List<String> orders = new LinkedList<>(); for (String orderBy : orderBys) { orders.add(table.getColumn(orderBy).getQuotedName());