📄 rdfrepository.java
字号:
// predicate nsId = _createIdForNamespace(pred.getNamespace()); _addRawTriplesSt.setInt(4, nsId); _addRawTriplesSt.setString(5, pred.getLocalName()); // object if (obj instanceof Resource) { // Resource columns if (obj instanceof BNode) { BNode bNode = (BNode)obj; _addRawTriplesSt.setInt(6, 0); // object namespace _addRawTriplesSt.setString(7, bNode.getID()); } else { URI uri = (URI)obj; nsId = _createIdForNamespace(uri.getNamespace()); _addRawTriplesSt.setInt(6, nsId); _addRawTriplesSt.setString(7, uri.getLocalName()); } // Literal columns _addRawTriplesSt.setLong(8, 0L); // labelHash _addRawTriplesSt.setNull(9, _rdbms.LANGUAGE_TYPE); // lang _addRawTriplesSt.setNull(10, _rdbms.LABEL_TYPE); // label _addRawTriplesSt.setBoolean(11, false); // obj is not a literal } else if (obj instanceof Literal) { // Literal columns Literal objLit = (Literal)obj; String label = objLit.getLabel(); String lang = objLit.getLanguage(); URI datatype = objLit.getDatatype(); // datatype if (datatype != null) { // Datatype should always be a URI nsId = _createIdForNamespace(datatype.getNamespace()); _addRawTriplesSt.setInt(6, nsId); _addRawTriplesSt.setString(7, datatype.getLocalName()); } else { _addRawTriplesSt.setInt(6, 0); // nsId _addRawTriplesSt.setString(7, ""); // lname } // labelHash _addRawTriplesSt.setLong(8, _getLabelHash(label)); // lang. Language does not apply to literals with a datatype. if (lang != null && datatype == null) { _addRawTriplesSt.setString(9, lang); } else { _addRawTriplesSt.setNull(9, _rdbms.LANGUAGE_TYPE); } // Label _addRawTriplesSt.setString(10, label); _addRawTriplesSt.setBoolean(11, true); // obj is a literal } _addRawTriplesSt.executeUpdate(); } catch (SQLException e) { throw new SailInternalException(e); } _statementsAdded = true; _rawTriplesCount++; if (_rawTriplesCount >= _triplesCommitInterval) { try { // Commit the transaction to the rawTriples table _closeUploadConnection(); // Process the raw triples _processRawTriples(); // Start a new transaction to the rawTriples table _prepareUploadConnection(); } catch (SQLException e) { throw new SailInternalException(e); } } } public int removeStatements(Resource subj, URI pred, Value obj) throws SailUpdateException { if (!_transactionStarted) { throw new SailUpdateException("No transaction started"); } // Register statements that should be removed in the expired triples // table. Note: only explicit statements can be removed. String query = "INSERT INTO " + EXPIRED_TRIPLES_TABLE + " SELECT id FROM " + TRIPLES_TABLE + " WHERE explicit = " + _rdbms.TRUE; // Subject if (subj != null) { int subjId = _getResourceId(subj); if (subjId == 0) { // subject not found, so no matching statements return 0; } query += " AND subj = " + subjId; } // Predicate if (pred != null) { int predId = _getURIId(pred); if (predId == 0) { // predicate not found, so no matching statements return 0; } query += " AND pred = " + predId; } // Object if (obj != null) { int objId = _getValueId(obj); if (objId == 0) { // object not found, so no matching statements return 0; } query += " AND obj = " + objId; } try { int count = _rdbms.executeUpdate(query); if (count > 0) { _rdbms.optimizeTable(EXPIRED_TRIPLES_TABLE, count); _statementsRemoved = true; } return count; } catch (SQLException e) { throw new SailInternalException(e); } } public void commitTransaction() { try { // Commit the transaction to the rawTriples table _closeUploadConnection(); if (_statementsRemoved) { _sailChangedEvent.setStatementsRemoved(true); _recordExpiredValues(); _removeExpiredStatements(); _removeExpiredValues(); } if (_statementsAdded) { _sailChangedEvent.setStatementsAdded(true); // Process the raw triples and add them to ADDED_TRIPLES_TABLE _processRawTriples(); _rdbms.optimizeTable(ADDED_TRIPLES_TABLE); _removeDuplicatesFromAddedTriples(); _processAddedTriples(); // Add these new triples to the triples table int newTriplesCount = _rdbms.copyRows(NEW_TRIPLES_TABLE, TRIPLES_TABLE); if (newTriplesCount == 0) { _rdbms.optimizeTable(TRIPLES_TABLE, newTriplesCount); _statementsAdded = false; } } if (_statementsAdded || _statementsRemoved) { // Hook for subclasses to do 'stuff' as a result of the added or // removed statements. _processChangedTriples(); _rdbms.clearTable(NEW_TRIPLES_TABLE); _rdbms.clearTable(EXPIRED_TRIPLES_TABLE); // Set the export status to 'dirty' _setExportStatusUpToDate(false); _statementsAdded = false; _statementsRemoved = false; } _notifySailChanged(_sailChangedEvent); } catch (SQLException e) { throw new SailInternalException(e); } finally { _sailChangedEvent = null; _transactionStarted = false; } } /** * Records which values (resources as well as literals) can potentially be * removed because they are referenced by expired statements. This method * uses the <tt>expiredTriples</tt> table to determine which statements are * expired and stores any referenced resources and literals in the * <tt>expiredResources</tt> and <tt>expiredLiterals</tt> tables, * respectively. This method should be called before the expired triples * have actually been removed. * * @see #_removeExpiredValues **/ protected void _recordExpiredValues() throws SQLException { // Resources _rdbms.executeUpdate("INSERT INTO " + EXPIRED_RESOURCES_TABLE + " SELECT t.subj FROM " + TRIPLES_TABLE + " t, " + EXPIRED_TRIPLES_TABLE + " expt" + " WHERE t.id = expt.id"); _rdbms.executeUpdate("INSERT INTO " + EXPIRED_RESOURCES_TABLE + " SELECT t.pred FROM " + TRIPLES_TABLE + " t, " + EXPIRED_TRIPLES_TABLE + " expt" + " WHERE t.id = expt.id"); _rdbms.executeUpdate("INSERT INTO " + EXPIRED_RESOURCES_TABLE + " SELECT t.obj FROM " + TRIPLES_TABLE + " t, " + EXPIRED_TRIPLES_TABLE + " expt" + " WHERE t.id = expt.id AND t.obj > 0"); // Literals _rdbms.executeUpdate("INSERT INTO " + EXPIRED_LITERALS_TABLE + " SELECT t.obj FROM " + TRIPLES_TABLE + " t, " + EXPIRED_TRIPLES_TABLE + " expt" + " WHERE t.id = expt.id AND t.obj < 0"); } /** * Removes any values that are no longer referenced by triples. This method * uses the value IDs recorded in the tables <tt>expiredResources</tt> and * <tt>expiredLiterals</tt> to determine which values are candidates for * removal. **/ protected void _removeExpiredValues() throws SQLException { // Delete the expired resources Connection con = _rdbms.getConnection(); java.sql.Statement st = con.createStatement(); ResultSet rs = st.executeQuery("SELECT DISTINCT expr.id" + " FROM " + EXPIRED_RESOURCES_TABLE + " expr " + " LEFT JOIN " + TRIPLES_TABLE + " t " + " ON expr.id = t.subj OR expr.id = t.pred OR expr.id = t.obj " + // used in a triple " LEFT JOIN " + LITERALS_TABLE + " l " + " ON expr.id = l.datatype " + // used as datatype " WHERE t.id IS NULL AND l.id IS NULL"); String[] idChunks = _chunkIdSet(rs, 3500); rs.close(); st.close(); con.close(); _rdbms.clearTable(EXPIRED_RESOURCES_TABLE); if (idChunks.length > 0) { // Remove the selected resources con = _rdbms.getConnection(); con.setAutoCommit(false); st = con.createStatement(); for (int i = 0; i < idChunks.length; i++) { st.executeUpdate("DELETE FROM " + RESOURCES_TABLE + " WHERE id IN " + idChunks[i]); } con.commit(); st.close(); con.close(); _rdbms.optimizeTable(RESOURCES_TABLE); } // Delete the expired literals con = _rdbms.getConnection(); st = con.createStatement(); rs = st.executeQuery("SELECT expl.id FROM " + EXPIRED_LITERALS_TABLE + " expl" + " LEFT JOIN " + TRIPLES_TABLE + " t" + " ON expl.id = t.obj" + " WHERE t.id IS NULL"); idChunks = _chunkIdSet(rs, 3500); rs.close(); st.close(); con.close(); _rdbms.clearTable(EXPIRED_LITERALS_TABLE); if (idChunks.length > 0) { // Remove the selected literals con = _rdbms.getConnection(); con.setAutoCommit(false); st = con.createStatement(); for (int i = 0; i < idChunks.length; i++) { st.executeUpdate("DELETE FROM " + LITERALS_TABLE + " WHERE id IN " + idChunks[i]); } con.commit(); st.close(); con.close(); _rdbms.optimizeTable(LITERALS_TABLE); } } /** * Removes the statements that are registered in EXPIRED_TRIPLES_TABLE and * any associated values that are no longer referenced as a result of the * removal. **/ protected void _removeExpiredStatements() throws SQLException { // Delete the expired statements Connection con = _rdbms.getConnection(); java.sql.Statement st = con.createStatement(); ResultSet rs = st.executeQuery("SELECT DISTINCT id FROM " + EXPIRED_TRIPLES_TABLE); String[] idChunks = _chunkIdSet(rs, 3500); rs.close(); st.close(); con.setAutoCommit(false); st = con.createStatement(); int count = 0; for (int i = 0; i < idChunks.length; i++) { count += st.executeUpdate("DELETE FROM " + TRIPLES_TABLE + " WHERE id IN " + idChunks[i]); _processChunkFromRemoveExpiredStatements(idChunks[i]); } con.commit(); st.close(); con.close(); _rdbms.optimizeTable(TRIPLES_TABLE, count); } protected void _processChunkFromRemoveExpiredStatements(String idList) throws SQLException { // do nothing, method is overriden by subclasses } protected void _processRawTriples() throws SQLException { _rdbms.optimizeTable(RAW_TRIPLES_TABLE); // RAW_TRIPLES_TABLE can contain new resources and literals. These // should be added to their respective tables first. _addNewResources(); _addNewLiterals(); // Now convert the resources and literals to IDs and copy the // rows to ADDED_TRIPLES_TABLE. _copyRawTriplesToAddedTriples(); _rdbms.clearTable(RAW_TRIPLES_TABLE); } /** * Adds resources from the RAW_TRIPLES_TABLE that are not yet in * RESOURCES_TABLE, to this last table. **/ protected void _addNewResources() throws SQLException { Connection addResourceCon = _rdbms.getConnection(); addResourceCon.setAutoCommit(false); PreparedStatement addResourceSt = addResourceCon.prepareStatement("INSERT INTO " + RESOURCES_TABLE + " VALUES(?, ?, ?)"); Connection con = _rdbms.getConnection(); java.sql.Statement st = con.createStatement(); // SUBJECT String localnamesAreNullOr = _rdbms.emptyStringIsNull() ? "rt.subjLname IS NULL AND r.localname IS NULL OR " : ""; String query = "SELECT DISTINCT rt.subjNs, rt.subjLname " + "FROM " + RAW_TRIPLES_TABLE + " rt " + "LEFT JOIN " + RESOURCES_TABLE + " r " + "ON rt.subjNs = r.namespace AND (" + localnamesAreNullOr + "rt.subjLname = r.localname) " + "WHERE r.namespace IS NULL"; _processNewResources(st.executeQuery(query), addResourceCon, addResourceSt); // PREDICATE localnamesAreNullOr = _rdbms.emptyStringIsNull() ? "rt.predLname IS NULL AND r.localname IS NULL OR " : ""; query = "SELECT DISTINCT rt.predNs, rt.predLname " + "FROM " + RAW_TRIPLES_TABLE + " rt " + "LEFT JOIN " + RESOURCES_TABLE + " r " + "ON rt.predNs = r.namespace AND (" + localnamesAreNullOr + "rt.predLname = r.localname) " + "WHERE r.namespace IS NULL"; _processNewResources(st.executeQuery(query), addResourceCon, addResourceSt); // OBJECT localnamesAreNullOr = _rdbms.emptyStringIsNull() ? "rt.objLname IS NULL AND r.localname IS NULL OR " : ""; query = "SELECT DISTINCT rt.objNs, rt.objLname " + "FROM " + RAW_TRIPLES_TABLE + " rt " + "LEFT JOIN " + RESOURCES_TABLE + " r " + "ON rt.objNs = r.namespace AND (" + localnamesAreNullOr + "rt.objLname = r.localname) " + "WHERE r.namespace IS NULL"; _processNewResources(st.executeQuery(query), addResourceCon, addResourceSt); st.close(); con.close(); addResourceSt.close(); addResourceCon.close(); } protected void _processNewResources(ResultSet rs, Connection addResourceCon, PreparedStatement addResourceSt) throws SQLException { int newCount = 0; while (rs.next()) { int ns = rs.getInt(1); String lname = rs.getString(2); if (lname == null) { lname = ""; } int resId = _getNextResourceId(); addResourceSt.setInt(1, resId); addResourceSt.setInt(2, ns); addResourceSt.setString(3, lname); addResourceSt.executeUpdate(); newCount++; } rs.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -