fulltextlucene.java

来自「非常棒的java数据库」· Java 代码 · 共 608 行 · 第 1/2 页

JAVA
608
字号
                    String schemaName = expr.getOriginalAliasName();
                    String tableName = expr.getColumnName();
                    q = q.substring(idx + " WHERE ".length());
                    Object[][] columnData = parseKey(conn, q);
                    Object[] row = new Object[] {  
                        schemaName,
                        tableName,
                        columnData[0],
                        columnData[1]
                    };
                    result.addRow(row);
                } else {
                    result.addRow(new Object[] { q });
                }
            }
            // TODO keep it open if possible
            reader.close();
        } catch (Exception e) {
            throw convertException(e);
        }
        return result;
    }

    private static void removeAllTriggers(Connection conn) throws SQLException {
        Statement stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TRIGGERS");
        Statement stat2 = conn.createStatement();
        while (rs.next()) {
            String schema = rs.getString("TRIGGER_SCHEMA");
            String name = rs.getString("TRIGGER_NAME");
            if (name.startsWith(TRIGGER_PREFIX)) {
                name = StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(name);
                stat2.execute("DROP TRIGGER " + name);
            }
        }
    }

    private static void removeIndexFiles(Connection conn) throws SQLException {
        String path = getIndexPath(conn);
        IndexModifier index = (IndexModifier) indexers.get(path);
        if (index != null) {
            indexers.remove(path);
            try {
                index.flush();
                index.close();
            } catch (IOException e) {
                throw convertException(e);
            }
        }
        FileSystem.getInstance(path).deleteRecursive(path);
    }

    private String getQuery(Object[] row) throws SQLException {
        StringBuffer buff = new StringBuffer();
        if (schemaName != null) {
            buff.append(StringUtils.quoteIdentifier(schemaName));
            buff.append(".");
        }
        buff.append(StringUtils.quoteIdentifier(tableName));
        buff.append(" WHERE ");
        for (int i = 0; i < keys.length; i++) {
            if (i > 0) {
                buff.append(" AND ");
            }
            int columnIndex = keys[i];
            buff.append(StringUtils.quoteIdentifier(columnNames[columnIndex]));
            Object o = row[columnIndex];
            if (o == null) {
                buff.append(" IS NULL");
            } else {
                buff.append("=");
                buff.append(quoteSQL(o, dataTypes[columnIndex]));
            }
        }
        String key = buff.toString();
        return key;
    }

    private String quoteString(String data) {
        if (data.indexOf('\'') < 0) {
            return "'" + data + "'";
        }
        StringBuffer buff = new StringBuffer(data.length() + 2);
        buff.append('\'');
        for (int i = 0; i < data.length(); i++) {
            char ch = data.charAt(i);
            if (ch == '\'') {
                buff.append(ch);
            }
            buff.append(ch);
        }
        buff.append('\'');
        return buff.toString();
    }

    private String quoteBinary(byte[] data) {
        return "'" + ByteUtils.convertBytesToString(data) + "'";
    }

    private String asString(Object data, int type) throws SQLException {
        if (data == null) {
            return "NULL";
        }
        switch (type) {
        case Types.BIT:
        case Types.BOOLEAN:
        case Types.INTEGER:
        case Types.BIGINT:
        case Types.DECIMAL:
        case Types.DOUBLE:
        case Types.FLOAT:
        case Types.NUMERIC:
        case Types.REAL:
        case Types.SMALLINT:
        case Types.TINYINT:
        case Types.DATE:
        case Types.TIME:
        case Types.TIMESTAMP:
        case Types.LONGVARCHAR:
        case Types.CHAR:
        case Types.VARCHAR:
            return data.toString();
        case Types.VARBINARY:
        case Types.LONGVARBINARY:
        case Types.BINARY:
        case Types.JAVA_OBJECT:
        case Types.CLOB:
        case Types.OTHER:
        case Types.BLOB:
        case Types.STRUCT:
        case Types.REF:
        case Types.NULL:
        case Types.ARRAY:
        case Types.DATALINK:
        case Types.DISTINCT:
            throw new SQLException("FULLTEXT", "Unsupported column data type: " + type);
        }
        return "";
    }

    private String quoteSQL(Object data, int type) throws SQLException {
        if (data == null) {
            return "NULL";
        }
        switch (type) {
        case Types.BIT:
        case Types.BOOLEAN:
        case Types.INTEGER:
        case Types.BIGINT:
        case Types.DECIMAL:
        case Types.DOUBLE:
        case Types.FLOAT:
        case Types.NUMERIC:
        case Types.REAL:
        case Types.SMALLINT:
        case Types.TINYINT:
            return data.toString();
        case Types.DATE:
        case Types.TIME:
        case Types.TIMESTAMP:
        case Types.LONGVARCHAR:
        case Types.CHAR:
        case Types.VARCHAR:
            return quoteString(data.toString());
        case Types.VARBINARY:
        case Types.LONGVARBINARY:
        case Types.BINARY:
            return quoteBinary((byte[]) data);
        case Types.JAVA_OBJECT:
        case Types.CLOB:
        case Types.OTHER:
        case Types.BLOB:
        case Types.STRUCT:
        case Types.REF:
        case Types.NULL:
        case Types.ARRAY:
        case Types.DATALINK:
        case Types.DISTINCT:
            throw new SQLException("FULLTEXT", "Unsupported key data type: " + type);
        }
        return "";
    }

    private void insert(Object[] row) throws SQLException {
        String query = getQuery(row);
        Document doc = new Document();
        doc.add(new Field(FIELD_QUERY, query, Field.Store.YES, Field.Index.UN_TOKENIZED));
        long time = System.currentTimeMillis();
        doc.add(new Field("modified", DateTools.timeToString(time, DateTools.Resolution.SECOND), Field.Store.YES, Field.Index.UN_TOKENIZED));
        StringBuffer allData = new StringBuffer();
        for (int i = 0; i < indexColumns.length; i++) {
            int index = indexColumns[i];
            String columnName = columnNames[index];
            String data = asString(row[index], dataTypes[index]);
            doc.add(new Field(FIELD_COLUMN_PREFIX + columnName, data, Field.Store.NO, Field.Index.TOKENIZED));
            if (i > 0) {
                allData.append(" ");
            }
            allData.append(data);
        }
        doc.add(new Field(FIELD_DATA, allData.toString(), Field.Store.NO, Field.Index.TOKENIZED));
        try {
            indexer.addDocument(doc);
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    private void delete(Object[] row) throws SQLException {
        String query = getQuery(row);
        try {
            Term term = new Term(FIELD_QUERY, query);
            indexer.deleteDocuments(term);
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    private static SQLException convertException(Exception e) {
        SQLException e2 = new SQLException("FULLTEXT", "Error while indexing document");
        e2.initCause(e);
        return e2;
    }

    private static void createTrigger(Connection conn, String schema, String table) throws SQLException {
        Statement stat = conn.createStatement();
        String trigger = StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(TRIGGER_PREFIX + table);
        stat.execute("DROP TRIGGER IF EXISTS " + trigger);
        StringBuffer buff = new StringBuffer("CREATE TRIGGER IF NOT EXISTS ");
        buff.append(trigger);
        buff.append(" AFTER INSERT, UPDATE, DELETE ON ");
        buff.append(StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(table));
        buff.append(" FOR EACH ROW CALL \"");
        buff.append(FullTextLucene.class.getName());
        buff.append("\"");
        stat.execute(buff.toString());
    }

    private static void indexExistingRows(Connection conn, String schema, String table) throws SQLException {
        FullTextLucene existing = new FullTextLucene();
        existing.init(conn, schema, null, table, false, INSERT);
        StringBuffer buff = new StringBuffer("SELECT * FROM ");
        buff.append(StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(table));
        ResultSet rs = conn.createStatement().executeQuery(buff.toString());
        int columnCount = rs.getMetaData().getColumnCount();
        while (rs.next()) {
            Object[] row = new Object[columnCount];
            for (int i = 0; i < columnCount; i++) {
                row[i] = rs.getObject(i + 1);
            }
            existing.fire(conn, null, row);
        }
    }

    private static IndexModifier getIndexModifier(Connection conn) throws SQLException {
        try {
            String path = getIndexPath(conn);
            IndexModifier indexer;
            synchronized (indexers) {
                indexer = (IndexModifier) indexers.get(path);
                if (indexer == null) {
                    // TODO: create flag = true means re-create
                    indexer = new IndexModifier(path, new StandardAnalyzer(), true);
                    indexers.put(path, indexer);
                }
            }
            return indexer;
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    private static String getIndexPath(Connection conn) throws SQLException {
        Statement stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("CALL DATABASE_PATH()");
        rs.next();
        String path = rs.getString(1);
        if (path == null) {
            throw new SQLException("FULLTEXT", "Fulltext search for in-memory databases is not supported.");
        }
        rs.close();
        return path;
    }

    private void setColumns(int[] index, ArrayList keys, ArrayList columns) throws SQLException {
        for (int i = 0; i < keys.size(); i++) {
            String key = (String) keys.get(i);
            int found = -1;
            for (int j = 0; found == -1 && j < columns.size(); j++) {
                String column = (String) columns.get(j);
                if (column.equals(key)) {
                    found = j;
                }
            }
            if (found < 0) {
                throw new SQLException("FULLTEXT", "Column not found: " + key);
            }
            index[i] = found;
        }
    }
//#endif

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?