📄 rdfsource.java
字号:
// zero value for denoting anonymous resources. Notice // that this is not an actual namespace! _rdbms.executeUpdate( "INSERT INTO " + NAMESPACES_TABLE + " VALUES(0, '', NULL, " + _rdbms.FALSE + ", " + _rdbms.FALSE + ")"); } } /** * Creates the RESOURCES_TABLE. */ protected void _createResourcesTable() throws SQLException { if (_schemaVersion == -1) { // No schema yet _rdbms.executeUpdate( "CREATE TABLE " + RESOURCES_TABLE + " (id " + _rdbms.ID_INT + " NOT NULL PRIMARY KEY," + " namespace " + _rdbms.ID_INT + " NOT NULL, " + " localname " + _rdbms.LOCALNAME + NN_ON_TEXT + "," + " UNIQUE(namespace, localname))"); // zero value for 'null' resources. This resource is used to // indicate that a literal does not have a datatype. _rdbms.executeUpdate( "INSERT INTO " + RESOURCES_TABLE + " VALUES(0, 0, '')"); } } /** * Creates the LITERALS_TABLE. */ protected void _createLiteralsTable() throws SQLException { if (_schemaVersion < 2) { // Old or non-existent table String OLD_LITERALS_TABLE = "old" + LITERALS_TABLE; if (_schemaVersion != -1) { // Old schema, rename current table _rdbms.dropIndex(LITERALS_TABLE, "labelKey"); _rdbms.renameTable(LITERALS_TABLE, OLD_LITERALS_TABLE); } // Create literals table _rdbms.executeUpdate( "CREATE TABLE " + LITERALS_TABLE + " (id " + _rdbms.ID_INT + " NOT NULL PRIMARY KEY," + " datatype " + _rdbms.ID_INT + " NOT NULL," + " labelHash " + _rdbms.LABEL_HASH + " NOT NULL," + " language " + _rdbms.LANGUAGE + "," + " label " + _rdbms.LABEL + NN_ON_TEXT + ")"); _rdbms.createIndex(LITERALS_TABLE, "labelHash"); if (_schemaVersion != -1) { // Copy all literals from the old to the new table, // replacing the 'labelKey' with a 'labelHash' Connection addLiteralCon = _rdbms.getConnection(); addLiteralCon.setAutoCommit(false); PreparedStatement addLiteralSt = addLiteralCon.prepareStatement( "INSERT INTO " + LITERALS_TABLE + " VALUES(?, ?, ?, ?, ?)"); Connection con = _rdbms.getConnection(); java.sql.Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT id, datatype, language, label FROM " + OLD_LITERALS_TABLE); int count = 0; while (rs.next()) { addLiteralSt.setInt(1, rs.getInt(1)); // id addLiteralSt.setInt(2, rs.getInt(2)); // datatype String lang = rs.getString(3); // language String label = rs.getString(4); // label if (label == null) { label = ""; } addLiteralSt.setLong(3, _getLabelHash(label)); if (lang != null) { addLiteralSt.setString(4, lang); } else { addLiteralSt.setNull(4, _rdbms.LANGUAGE_TYPE); } addLiteralSt.setString(5, label); addLiteralSt.executeUpdate(); count++; } rs.close(); st.close(); con.close(); addLiteralCon.commit(); addLiteralSt.close(); addLiteralCon.close(); _rdbms.optimizeTable(LITERALS_TABLE, count); _rdbms.dropTable(OLD_LITERALS_TABLE); } } } /** * Creates the TRIPLES_TABLE. */ protected void _createTriplesTable() throws SQLException { if (_schemaVersion == -1) { // No schema yet _createTriplesTable(TRIPLES_TABLE, true); _rdbms.createIndex(TRIPLES_TABLE, "subj"); _rdbms.createIndex(TRIPLES_TABLE, "pred"); _rdbms.createIndex(TRIPLES_TABLE, "obj"); _rdbms.createIndex(TRIPLES_TABLE, new String[]{"subj", "pred"}, false); _rdbms.createIndex(TRIPLES_TABLE, new String[]{"subj", "obj"}, false); _rdbms.createIndex(TRIPLES_TABLE, new String[]{"pred", "obj"}, false); } else if (_schemaVersion < 4) { _rdbms.renameTableColumn(TRIPLES_TABLE, "subject" , "subj", _rdbms.ID_INT+" NOT NULL"); _rdbms.renameTableColumn(TRIPLES_TABLE, "predicate", "pred", _rdbms.ID_INT+" NOT NULL"); _rdbms.renameTableColumn(TRIPLES_TABLE, "object" , "obj" , _rdbms.ID_INT+" NOT NULL"); } } /** * Creates a table for storing triples. The table will get the specified * name and will have four integer columns (id, subject, predicate and * object), and one boolean column (explicit). If 'uniqueRows' is true, a * unique index will be creates on the columns (subject, predicate, object). */ protected void _createTriplesTable(String tableName, boolean uniqueRows) throws SQLException { StringBuffer update = new StringBuffer(200); update.append("CREATE TABLE " + tableName + " "); update.append("(id " + _rdbms.ID_INT + " NOT NULL,"); update.append(" subj " + _rdbms.ID_INT + " NOT NULL,"); update.append(" pred " + _rdbms.ID_INT + " NOT NULL,"); update.append(" obj " + _rdbms.ID_INT + " NOT NULL,"); update.append(" explicit " + _rdbms.BOOLEAN + " NOT NULL"); if (uniqueRows) { update.append(", UNIQUE(subj, pred, obj)"); } update.append(")"); _rdbms.executeUpdate(update.toString()); }/*--------------------------+| Getting/setting meta info |+--------------------------*/ /** * Sets or changes a value for a specific key in the REP_INFO_TABLE. */ protected void _setRepInfo(String key, String value) throws SQLException { // Remove any previous value for this key: _rdbms.executeUpdate( "DELETE FROM " + REP_INFO_TABLE + " WHERE infokey = '" + _rdbms.escapeString(key) + "'"); // Insert the new value _rdbms.executeUpdate( "INSERT INTO " + REP_INFO_TABLE + " VALUES ('" + _rdbms.escapeString(key) + "', '" + _rdbms.escapeString(value) + "')"); } /** * Gets the value for a specific key from the REP_INFO_TABLE. */ protected String _getRepInfo(String key) throws SQLException { String result = null; Connection con = _rdbms.getConnection(); java.sql.Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT infovalue FROM " + REP_INFO_TABLE + " WHERE infokey = '" + _rdbms.escapeString(key) + "'"); if (rs.next()) { result = rs.getString(1); } rs.close(); st.close(); con.close(); return result; } /** * Sets the status of the namespaces table's <tt>export</tt> column. * * @param upToDate Flag indicating whether the export status is up-to-date. **/ protected void _setExportStatusUpToDate(boolean upToDate) throws SQLException { if (_exportStatusUpToDate != upToDate) { _exportStatusUpToDate = upToDate; if (upToDate) { _setRepInfo(KEY_EXPORT_FLAGS, VALUE_UP_TO_DATE); } else { _setRepInfo(KEY_EXPORT_FLAGS, VALUE_DIRTY); } } } /** * Gets the status of the namespaces table's <tt>export</tt> column. * * @return <tt>true</tt> if the values in the <tt>export</tt> column are * up-to-date, <tt>false</tt> otherwise. **/ protected boolean _exportStatusUpToDate() { return _exportStatusUpToDate; }/*----------------------------------+| Initialization of local variables |+----------------------------------*/ /** * Initializes the internal namespace cache and fills it with the contents * of the NAMESPACES_TABLE. */ protected void _initNamespaceCache() throws SQLException { _namespaceTable.clear(); _namespaceList.clear(); Connection con = _rdbms.getConnection(); java.sql.Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT id, prefix, name, export " + "FROM " + NAMESPACES_TABLE + " WHERE id <> 0"); int maxId = 0; while (rs.next()) { int id = rs.getInt(1); String prefix = rs.getString(2); String name = rs.getString(3); boolean export = rs.getBoolean(4); if (prefix == null) { prefix = ""; } RdbmsNamespace ns = new RdbmsNamespace(id, prefix, name, export); _namespaceTable.put(name, ns); _namespaceList.add(ns); if (id > maxId) { maxId = id; } } rs.close(); st.close(); con.close(); // Next namespace id to be assigned is max + 1 _nextNamespaceId = maxId + 1; // Initialize _namespaceNames array _namespaceNames = new String[maxId + 1]; for (int i = 0; i < _namespaceList.size(); i++) { RdbmsNamespace ns = (RdbmsNamespace)_namespaceList.get(i); _namespaceNames[ns.getId()] = ns.getName(); } } protected int _getNextNamespaceId() { return _nextNamespaceId++; }/*-----------------------+| Methods from RdfSource |+-----------------------*/ public ValueFactory getValueFactory() { return this; } public StatementIterator getStatements(Resource subj, URI pred, Value obj) { return getStatements(subj, pred, obj, false); } public StatementIterator getStatements( Resource subj, URI pred, Value obj, boolean explicitOnly) { int subjId = 0; int predId = 0; int objId = 0; if (subj != null) { // Subject specified. subjId = _getResourceId(subj); if (subjId == 0) { // Subject not found, so no matching statements. return new EmptyStatementIterator(); } } if (pred != null) { // Predicate specified. predId = _getURIId(pred); if (predId == 0) { // Predicate not found, so no matching statements. return new EmptyStatementIterator(); } } if (obj != null) { // Object specified. objId = _getValueId(obj); if (objId == 0) { // Object not found, so no matching statements. return new EmptyStatementIterator(); } } // The StatementIterator requires 2 queries, one where triples.obj // is joined with resources.id and one where triples.obj is joined // with literals.id. String queryResources = null; String queryLiterals = null; if (obj instanceof Resource) { // Object is a resource, thus there is no need to build the // query where triples.obj is joined with literals.id, // because it will always fail. queryResources = _buildGetStatementsQuery( subjId, predId, objId, true, explicitOnly); } else if (obj instanceof Literal) { // Object is a literal, thus there is no need to build the // query where triples.obj is joined with resources.id, // because it will always fail. queryLiterals = _buildGetStatementsQuery( subjId, predId, objId, false, explicitOnly); } else { // Both queries are needed. queryResources = _buildGetStatementsQuery( subjId, predId, objId, true, explicitOnly); queryLiterals = _buildGetStatementsQuery( subjId, predId, objId, false, explicitOnly); } try { Connection con = _rdbms.getConnection(); return new RdbmsStatementIterator(this, _namespaceNames, con, queryResources, queryLiterals, subj, pred, obj); } catch (SQLException e) { throw new SailInternalException(e); } } protected String _buildGetStatementsQuery(int subjId, int predId, int objId, boolean queryResources, boolean explicitOnly) { // Build select, from and where clause seperately StringBuffer select = new StringBuffer(100); StringBuffer from = new StringBuffer(200); StringBuffer where = new StringBuffer(200); // Commas need to be appended after the first parts have been written. boolean writeCommas = false; // subject if (subjId != 0) { // subject is specified where.append("t.subj = " + subjId + " AND "); } else { // subject is a wildcard select.append("r1.id, r1.namespace, r1.localname"); from.append(RESOURCES_TABLE + " r1"); where.append("t.subj = r1.id AND "); writeCommas = true; } // predicate if (predId != 0) { // predicate is specified where.append("t.pred = " + predId + " AND "); } else { // predicate is a wildcard if (writeCommas) { select.append(", "); from.append(", "); } select.append("r2.id, r2.namespace, r2.localname"); from.append(RESOURCES_TABLE + " r2"); where.append("t.pred = r2.id AND "); writeCommas = true; } // object if (objId != 0) { // object is specified where.append("t.obj = " + objId); } else { // object is a wildcard if (writeCommas) { select.append(", "); from.append(", "); } if (queryResources) { // object is a resource select.append("r3.id, r3.namespace, r3.localname"); from.append(RESOURCES_TABLE + " r3"); where.append("t.obj > 0 AND t.obj = r3.id"); } else { // object is a literal select.append("l.id, dt.id, dt.namespace, dt.localname, l.language, l.label"); from.append(LITERALS_TABLE + " l, " + RESOURCES_TABLE + " dt"); where.append("t.obj < 0 AND t.obj = l.id AND l.datatype = dt.id"); } } // Build the complete query StringBuffer query = new StringBuffer(400); query.append("SELECT "); if (select.length() == 0) { // Select clause is still empty because all parameters are specified query.append("t.id"); } else { query.append(select.toString()); } query.append(" FROM " + TRIPLES_TABLE + " t"); if (from.length() > 0) { // from clause is not empty query.append(", " + from.toString()); } query.append(" WHERE " + where.toString()); if (explicitOnly) { query.append(" AND t.explicit = " + _rdbms.TRUE); } return query.toString(); } public boolean hasStatement(Resource subj, URI pred, Value obj) { return hasStatement(subj, pred, obj, false); } /** * Merges all TriplePatterns to one large SQL-join and includes as much of * the boolean constraints as possible. */ public Query optimizeQuery(Query qc) { if (qc instanceof GraphPatternQuery) { _optimizeGraphPatternQuery( (GraphPatternQuery)qc ); } else if (qc instanceof SetOperator) { SetOperator setOp = (SetOperator)qc; optimizeQuery(setOp.getLeftArg()); optimizeQuery(setOp.getRightArg()); } return qc; } private void _optimizeGraphPatternQuery(GraphPatternQuery graphPatternQuery) { GraphPattern graphPattern = graphPatternQuery.getGraphPattern(); List pathExpressions = graphPattern.getPathExpressions(); if (pathExpressions.size() <= 1) { // Query contains too few path expressions for the RDBMS-specific
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -