@Test public void testSize() throws Exception { assertEquals("Size of empty repository should be 0", 0, con.size()); // Add some data to the repository con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.addStatement(picasso, paints, guernica, context1); con.commit(); assertEquals("Size of repository should be 5", 5, con.size()); assertEquals("Size of named context should be 3", 3, con.size(context1)); URI unknownContext = new URIImpl(EXAMPLE_NS + "unknown"); assertEquals("Size of unknown context should be 0", 0, con.size(unknownContext)); URIImpl uriImplContext1 = new URIImpl(context1.toString()); assertEquals( "Size of named context (defined as URIImpl) should be 3", 3, con.size(uriImplContext1)); }
@Test public void testQueryBindings() throws Exception { // Add some data to the repository con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.addStatement(picasso, paints, guernica, context1); con.commit(); // Query 1 ParsedTupleQuery tupleQuery = QueryParserUtil.parseTupleQuery( QueryLanguage.SERQL, "select X from {X} rdf:type {Y} rdf:type {rdfs:Class}", null); TupleExpr tupleExpr = tupleQuery.getTupleExpr(); MapBindingSet bindings = new MapBindingSet(2); CloseableIteration<? extends BindingSet, QueryEvaluationException> iter; iter = con.evaluate(tupleExpr, null, bindings, false); int resultCount = verifyQueryResult(iter, 1); assertEquals("Wrong number of query results", 2, resultCount); bindings.addBinding("Y", painter); iter = con.evaluate(tupleExpr, null, bindings, false); resultCount = verifyQueryResult(iter, 1); assertEquals("Wrong number of query results", 1, resultCount); bindings.addBinding("Z", painting); iter = con.evaluate(tupleExpr, null, bindings, false); resultCount = verifyQueryResult(iter, 1); assertEquals("Wrong number of query results", 1, resultCount); bindings.removeBinding("Y"); iter = con.evaluate(tupleExpr, null, bindings, false); resultCount = verifyQueryResult(iter, 1); assertEquals("Wrong number of query results", 2, resultCount); // Query 2 tupleQuery = QueryParserUtil.parseTupleQuery( QueryLanguage.SERQL, "select X from {X} rdf:type {Y} rdf:type {rdfs:Class} where Y = Z", null); tupleExpr = tupleQuery.getTupleExpr(); bindings.clear(); iter = con.evaluate(tupleExpr, null, bindings, false); resultCount = verifyQueryResult(iter, 1); assertEquals("Wrong number of query results", 0, resultCount); bindings.addBinding("Z", painter); iter = con.evaluate(tupleExpr, null, bindings, false); resultCount = verifyQueryResult(iter, 1); assertEquals("Wrong number of query results", 1, resultCount); }
@Test public void testBNodeReuse() throws Exception { con.begin(); con.addStatement(RDF.VALUE, RDF.VALUE, RDF.VALUE); assertEquals(1, con.size()); BNode b1 = vf.createBNode(); con.addStatement(b1, RDF.VALUE, b1); con.removeStatements(b1, RDF.VALUE, b1); assertEquals(1, con.size()); BNode b2 = vf.createBNode(); con.addStatement(b2, RDF.VALUE, b2); con.addStatement(b1, RDF.VALUE, b1); assertEquals(3, con.size()); con.commit(); }
@Test public void testDualConnections() throws Exception { SailConnection con2 = sail.getConnection(); try { assertEquals(0, countAllElements()); con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.commit(); assertEquals(4, countAllElements()); con2.begin(); con2.addStatement(RDF.NIL, RDF.TYPE, RDF.LIST); String query = "SELECT S, P, O FROM {S} P {O}"; ParsedTupleQuery tupleQuery = QueryParserUtil.parseTupleQuery(QueryLanguage.SERQL, query, null); assertEquals( 5, countElements( con2.evaluate( tupleQuery.getTupleExpr(), null, EmptyBindingSet.getInstance(), false))); Runnable clearer = new Runnable() { public void run() { try { con.begin(); con.clear(); con.commit(); } catch (SailException e) { throw new RuntimeException(e); } } }; Thread thread = new Thread(clearer); thread.start(); Thread.yield(); Thread.yield(); con2.commit(); thread.join(); } finally { con2.close(); } }
@Test public void testClose() { try { con.close(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); fail("Operation on connection after close should result in IllegalStateException"); } catch (IllegalStateException e) { // do nothing, this is expected } catch (SailException e) { fail(e.getMessage()); } }
@Test public void testCreateURI2() throws Exception { URI picasso1 = vf.createURI(EXAMPLE_NS + PICASSO); URI picasso2 = vf.createURI(EXAMPLE_NS, PICASSO); con.begin(); con.addStatement(picasso1, paints, guernica); con.addStatement(picasso2, paints, guernica); con.commit(); assertEquals( "createURI(Sring) and createURI(String, String) should create equal URIs", 1, con.size()); }
@Test public void testGetContextIDs() throws Exception { assertEquals(0, countElements(con.getContextIDs())); // load data con.begin(); con.addStatement(picasso, paints, guernica, context1); assertEquals(1, countElements(con.getContextIDs())); assertEquals(context1, first(con.getContextIDs())); con.removeStatements(picasso, paints, guernica, context1); assertEquals(0, countElements(con.getContextIDs())); con.commit(); assertEquals(0, countElements(con.getContextIDs())); con.begin(); con.addStatement(picasso, paints, guernica, context2); assertEquals(1, countElements(con.getContextIDs())); assertEquals(context2, first(con.getContextIDs())); con.commit(); }
@Test public void testRemoveAndClear() throws Exception { // Add some data to the repository con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.addStatement(picasso, paints, guernica, context1); con.commit(); // Test removal of statements con.begin(); con.removeStatements(painting, RDF.TYPE, RDFS.CLASS); con.commit(); assertEquals("Repository should contain 4 statements in total", 4, countAllElements()); assertEquals("Named context should contain 3 statements", 3, countContext1Elements()); assertEquals( "Statement (Painting, type, Class) should no longer be in the repository", 0, countQueryResults("select 1 from {ex:Painting} rdf:type {rdfs:Class}")); con.begin(); con.removeStatements(null, null, null, context1); con.commit(); assertEquals("Repository should contain 1 statement in total", 1, countAllElements()); assertEquals("Named context should be empty", 0, countContext1Elements()); con.begin(); con.clear(); con.commit(); assertEquals("Repository should no longer contain any statements", 0, countAllElements()); }
@Test public void testAddWhileQuerying() throws Exception { // Add some data to the repository con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter); con.addStatement(guernica, RDF.TYPE, painting); con.addStatement(picasso, paints, guernica); con.commit(); ParsedTupleQuery tupleQuery = QueryParserUtil.parseTupleQuery(QueryLanguage.SERQL, "SELECT C FROM {} rdf:type {C}", null); CloseableIteration<? extends BindingSet, QueryEvaluationException> iter; iter = con.evaluate(tupleQuery.getTupleExpr(), null, EmptyBindingSet.getInstance(), false); con.begin(); while (iter.hasNext()) { BindingSet bindings = iter.next(); Value c = bindings.getValue("C"); if (c instanceof Resource) { con.addStatement((Resource) c, RDF.TYPE, RDFS.CLASS); } } con.commit(); assertEquals(3, countElements(con.getStatements(null, RDF.TYPE, RDFS.CLASS, false))); // simulate auto-commit tupleQuery = QueryParserUtil.parseTupleQuery(QueryLanguage.SERQL, "SELECT P FROM {} P {}", null); iter = con.evaluate(tupleQuery.getTupleExpr(), null, EmptyBindingSet.getInstance(), false); while (iter.hasNext()) { BindingSet bindings = iter.next(); Value p = bindings.getValue("P"); if (p instanceof URI) { con.begin(); con.addStatement((URI) p, RDF.TYPE, RDF.PROPERTY); con.commit(); } } assertEquals(2, countElements(con.getStatements(null, RDF.TYPE, RDF.PROPERTY, false))); }
protected void testValueRoundTrip(Resource subj, URI pred, Value obj) throws Exception { con.begin(); con.addStatement(subj, pred, obj); con.commit(); CloseableIteration<? extends Statement, SailException> stIter = con.getStatements(null, null, null, false); try { assertTrue(stIter.hasNext()); Statement st = stIter.next(); assertEquals(subj, st.getSubject()); assertEquals(pred, st.getPredicate()); assertEquals(obj, st.getObject()); assertTrue(!stIter.hasNext()); } finally { stIter.close(); } ParsedTupleQuery tupleQuery = QueryParserUtil.parseTupleQuery( QueryLanguage.SERQL, "SELECT S, P, O FROM {S} P {O} WHERE P = <" + pred.stringValue() + ">", null); CloseableIteration<? extends BindingSet, QueryEvaluationException> iter; iter = con.evaluate(tupleQuery.getTupleExpr(), null, EmptyBindingSet.getInstance(), false); try { assertTrue(iter.hasNext()); BindingSet bindings = iter.next(); assertEquals(subj, bindings.getValue("S")); assertEquals(pred, bindings.getValue("P")); assertEquals(obj, bindings.getValue("O")); assertTrue(!iter.hasNext()); } finally { iter.close(); } }
@Test public void testOldURI() throws Exception { assertEquals(0, countAllElements()); con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.addStatement(picasso, paints, guernica, context1); assertEquals(5, countAllElements()); con.commit(); con.begin(); con.clear(); con.commit(); con.begin(); con.addStatement(picasso, paints, guernica, context1); con.commit(); assertEquals(1, countAllElements()); }
/** Not compatible with our MVCC semantics. */ private void __testMultiThreadedAccess() { Runnable runnable = new Runnable() { SailConnection sharedCon = con; public void run() { assertTrue(sharedCon != null); try { while (sharedCon.isActive()) { Thread.sleep(10); } sharedCon.begin(); sharedCon.addStatement(painter, RDF.TYPE, RDFS.CLASS); sharedCon.commit(); // wait a bit to allow other thread to add stuff as well. Thread.sleep(500L); CloseableIteration<? extends Statement, SailException> result = sharedCon.getStatements(null, null, null, true); assertTrue(result.hasNext()); int numberOfStatements = 0; while (result.hasNext()) { numberOfStatements++; Statement st = result.next(); assertTrue(st.getSubject().equals(painter) || st.getSubject().equals(picasso)); assertTrue(st.getPredicate().equals(RDF.TYPE)); assertTrue(st.getObject().equals(RDFS.CLASS) || st.getObject().equals(painter)); } assertTrue( "we should have retrieved statements from both threads", numberOfStatements == 2); } catch (SailException e) { e.printStackTrace(); fail(e.getMessage()); } catch (InterruptedException e) { fail(e.getMessage()); } // let this thread sleep so the other thread can invoke close() // first. try { Thread.sleep(1000L); // the connection should now be closed (by the other thread), // invoking any further operation should cause a // IllegalStateException sharedCon.getStatements(null, null, null, true); fail("should have caused an IllegalStateException"); } catch (InterruptedException e) { fail(e.getMessage()); } catch (SailException e) { e.printStackTrace(); fail(e.getMessage()); } catch (IllegalStateException e) { // do nothing, this is the expected behaviour } } }; // end anonymous class declaration // execute the other thread Thread newThread = new Thread(runnable, "B (parallel)"); newThread.start(); try { while (con.isActive()) { Thread.sleep(10); } con.begin(); con.addStatement(picasso, RDF.TYPE, painter); con.commit(); // let this thread sleep to enable other thread to finish its business. Thread.sleep(1000L); con.close(); } catch (SailException e) { e.printStackTrace(); fail(e.getMessage()); } catch (InterruptedException e) { fail(e.getMessage()); } }
@Test public void testContexts() throws Exception { con.begin(); // Add schema data to the repository, no context con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); // Add stuff about picasso to context1 con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.addStatement(picasso, paints, guernica, context1); // Add stuff about rembrandt to context2 con.addStatement(rembrandt, RDF.TYPE, painter, context2); con.addStatement(nightwatch, RDF.TYPE, painting, context2); con.addStatement(rembrandt, paints, nightwatch, context2); con.commit(); assertEquals("context1 should contain 3 statements", 3, countContext1Elements()); assertEquals( "context2 should contain 3 statements", 3, countElements(con.getStatements(null, null, null, false, context2))); assertEquals("Repository should contain 8 statements", 8, countAllElements()); assertEquals( "statements without context should equal 2", 2, countElements(con.getStatements(null, null, null, false, (Resource) null))); assertEquals( "Statements without context and statements in context 1 together should total 5", 5, countElements(con.getStatements(null, null, null, false, null, context1))); assertEquals( "Statements without context and statements in context 2 together should total 5", 5, countElements(con.getStatements(null, null, null, false, null, context2))); assertEquals( "Statements in context 1 and in context 2 together should total 6", 6, countElements(con.getStatements(null, null, null, false, context1, context2))); // remove two statements from context1. con.begin(); con.removeStatements(picasso, null, null, context1); con.commit(); assertEquals("context1 should contain 1 statements", 1, countContext1Elements()); assertEquals("Repository should contain 6 statements", 6, countAllElements()); assertEquals( "Statements without context and statements in context 1 together should total 3", 3, countElements(con.getStatements(null, null, null, false, null, context1))); assertEquals( "Statements without context and statements in context 2 together should total 5", 5, countElements(con.getStatements(null, null, null, false, context2, null))); assertEquals( "Statements in context 1 and in context 2 together should total 4", 4, countElements(con.getStatements(null, null, null, false, context1, context2))); }
@Test public void testAddData() throws Exception { // Add some data to the repository con.begin(); con.addStatement(painter, RDF.TYPE, RDFS.CLASS); con.addStatement(painting, RDF.TYPE, RDFS.CLASS); con.addStatement(picasso, RDF.TYPE, painter, context1); con.addStatement(guernica, RDF.TYPE, painting, context1); con.addStatement(picasso, paints, guernica, context1); con.commit(); assertEquals("Repository should contain 5 statements in total", 5, countAllElements()); assertEquals("Named context should contain 3 statements", 3, countContext1Elements()); assertEquals( "Repository should have 1 context identifier", 1, countElements(con.getContextIDs())); assertEquals( "Repository should contain 5 statements in total", 5, countQueryResults("select * from {S} P {O}")); // Check for presence of the added statements assertEquals( "Statement (Painter, type, Class) should be in the repository", 1, countQueryResults("select 1 from {ex:Painter} rdf:type {rdfs:Class}")); assertEquals( "Statement (picasso, type, Painter) should be in the repository", 1, countQueryResults("select 1 from {ex:picasso} rdf:type {ex:Painter}")); // Check for absense of non-added statements assertEquals( "Statement (Painter, paints, Painting) should not be in the repository", 0, countQueryResults("select 1 from {ex:Painter} ex:paints {ex:Painting}")); assertEquals( "Statement (picasso, creates, guernica) should not be in the repository", 0, countQueryResults("select 1 from {ex:picasso} ex:creates {ex:guernica}")); // Various other checks assertEquals( "Repository should contain 2 statements matching (picasso, _, _)", 2, countQueryResults("select * from {ex:picasso} P {O}")); assertEquals( "Repository should contain 1 statement matching (picasso, paints, _)", 1, countQueryResults("select * from {ex:picasso} ex:paints {O}")); assertEquals( "Repository should contain 4 statements matching (_, type, _)", 4, countQueryResults("select * from {S} rdf:type {O}")); assertEquals( "Repository should contain 2 statements matching (_, _, Class)", 2, countQueryResults("select * from {S} P {rdfs:Class}")); assertEquals( "Repository should contain 0 statements matching (_, _, type)", 0, countQueryResults("select * from {S} P {rdf:type}")); }