public function testSerializerWithMultipleSubjects() { $g = new MongoGraph(); $docs = json_decode(file_get_contents(dirname(__FILE__) . '/data/resources.json'), true); foreach ($docs as $d) { $g->add_tripod_array($d); } $expected = "<http://life.ac.uk/resources/BFBC6A06-A8B0-DED8-53AA-8E80DB44CC53> <http://purl.org/dc/terms/title> \"Title of resource 2\" <http://talisaspire.com/> .\n<http://life.ac.uk/resources/836E7CAD-63D2-63A0-B1CB-AA6A7E54A5C9> <http://purl.org/dc/terms/title> \"Title of resource 1\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://purl.org/dc/terms/isVersionOf> <http://talisaspire.com/works/4d101f63c10a6> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://purl.org/dc/terms/source> <http://life.ac.uk/resources/BFBC6A06-A8B0-DED8-53AA-8E80DB44CC53> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://purl.org/dc/terms/source> <http://life.ac.uk/resources/836E7CAD-63D2-63A0-B1CB-AA6A7E54A5C9> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://purl.org/dc/terms/subject> <http://talisaspire.com/disciplines/physics> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://purl.org/ontology/bibo/isbn13> \"9780393929690\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#bookmarkReferences> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/bookmarks> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#foo> \"wibble\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#jacsUri> <http://jacs3.dataincubator.org/f300> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#jacsUri> <http://jacs3.dataincubator.org/f340> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#listReferences> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/lists> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#openLibraryUri> <http://openlibrary.org/books/OL10157958M> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/schema#preferredMetadata> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/metadata> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#author> \"Ohanian\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#discipline> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#isbn> \"9780393929690\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"Engineering: general\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"PHYSICS\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"Science\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#title> \"Physics 3rd Edition\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#title> \"Physics for Engineers and Scientists\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#topic> \"engineering: general\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#topic> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#topic> \"science\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://talisaspire.com/searchTerms/schema#usedAt> \"0071\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Book> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Resource> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA> <http://www.w3.org/2002/07/owl#sameAs> <http://talisaspire.com/isbn/9780393929690> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://purl.org/dc/terms/isVersionOf> <http://talisaspire.com/works/4d101f63c10a6> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://purl.org/dc/terms/source> <http://life.ac.uk/resources/836E7CAD-63D2-63A0-B1CB-AA6A7E54A5C9> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://purl.org/dc/terms/source> <http://life.ac.uk/resources/BFBC6A06-A8B0-DED8-53AA-8E80DB44CC53> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://purl.org/dc/terms/subject> <http://talisaspire.com/disciplines/physics> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://purl.org/ontology/bibo/isbn13> \"9780393929691\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#bookmarkReferences> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/bookmarks> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#foo> \"wibble\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#jacsUri> <http://jacs3.dataincubator.org/f300> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#jacsUri> <http://jacs3.dataincubator.org/f340> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#listReferences> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/lists> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#openLibraryUri> <http://openlibrary.org/books/OL10157958M> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/schema#preferredMetadata> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/metadata> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#author> \"Ohanian\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#discipline> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#isbn> \"9780393929690\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"Engineering: general\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"PHYSICS\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"Science\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#title> \"Physics 3rd Edition\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#title> \"Physics for Engineers and Scientists\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#topic> \"engineering: general\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#topic> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#topic> \"science\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://talisaspire.com/searchTerms/schema#usedAt> \"0071\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Book> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Resource> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA-2> <http://www.w3.org/2002/07/owl#sameAs> <http://talisaspire.com/isbn/9780393929690> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://purl.org/dc/terms/isVersionOf> <http://talisaspire.com/works/4d101f63c10a6> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://purl.org/dc/terms/source> <http://life.ac.uk/resources/836E7CAD-63D2-63A0-B1CB-AA6A7E54A5C9> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://purl.org/dc/terms/source> <http://life.ac.uk/resources/BFBC6A06-A8B0-DED8-53AA-8E80DB44CC53> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://purl.org/dc/terms/subject> <http://talisaspire.com/disciplines/physics> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://purl.org/ontology/bibo/isbn13> \"1234567890123\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#bookmarkReferences> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/bookmarks> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#foo> \"wibble\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#jacsUri> <http://jacs3.dataincubator.org/f300> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#jacsUri> <http://jacs3.dataincubator.org/f340> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#listReferences> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/lists> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#openLibraryUri> <http://openlibrary.org/books/OL10157958M> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/schema#preferredMetadata> <http://talisaspire.com/resources/3SplCtWGPqEyXcDiyhHQpA/metadata> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#author> \"Ohanian\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#discipline> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#isbn> \"1234567890\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"Engineering: general\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"PHYSICS\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#openLibrarySubject> \"Science\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#title> \"Mahommah Gardo Baquaqua. Biography of Mahommah G. Baquaqua, a Native of Zoogoo, in the Interior of Africa. (A Convert to Christianity,) With a Description of That Part of the World; Including the Manners and Customs of the Inhabitants, Their Religious Notions, Form of Government, Laws, Appearance of the Country, Buildings, Agriculture, Manufactures, Shepherds and Herdsmen, Domestic Animals, Marriage Ceremonials, Funeral Services, Styles of Dress, Trade and Commerce, Modes of Warfare, System of Slavery, &c., &c. Mahommah's Early Life, His Education, His Capture and Slavery in Western Africa and Brazil, His Escape to the United States, from Thence to Hayti, (the City of Port Au Prince,) His Reception by the Baptist Missionary There, The Rev. W. L. Judd; His Conversion to Christianity, Baptism, and Return to This Country, His Views, Objects and Aim. Written and Revised from His Own Words, by Samuel Moore, Esq., Late Publisher of the "North of England Shipping Gazette," Author of Several Popular Works, and Editor of Sundry Reform Papers.\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#topic> \"engineering: general\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#topic> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#topic> \"science\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://talisaspire.com/searchTerms/schema#usedAt> \"0071\" <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Book> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#ResourceForTruncating> <http://talisaspire.com/> .\n<http://talisaspire.com/resources/indexKeyTooLarge> <http://www.w3.org/2002/07/owl#sameAs> <http://talisaspire.com/isbn/9780393929690> <http://talisaspire.com/> .\n<http://jacs3.dataincubator.org/f300> <http://purl.org/dc/terms/title> \"First title\" <http://talisaspire.com/> .\n<http://jacs3.dataincubator.org/f300> <http://purl.org/dc/terms/title> \"Second title\" <http://talisaspire.com/> .\n<http://jacs3.dataincubator.org/f340> <http://purl.org/dc/terms/title> \"First title\" <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://purl.org/dc/terms/subject> <http://talisaspire.com/disciplines/physics> <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://purl.org/ontology/bibo/isbn13> \"9780393929691\" <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://purl.org/ontology/bibo/isbn13> \"9780393929691-2\" <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://talisaspire.com/searchTerms/schema#discipline> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://talisaspire.com/schema#seeAlso> <http://talisaspire.com/works/4d101f63c10a6-2> <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Book> <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Work> <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6-2> <http://purl.org/dc/terms/subject> <http://talisaspire.com/disciplines/physics> <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6-2> <http://purl.org/ontology/bibo/isbn13> \"9780393929691\" <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6-2> <http://talisaspire.com/searchTerms/schema#discipline> \"physics\" <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6-2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Book> <http://talisaspire.com/> .\n<http://talisaspire.com/works/4d101f63c10a6-2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Work> <http://talisaspire.com/> .\n<http://talisaspire.com/works/lockedDoc> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Book> <http://talisaspire.com/> .\n<http://talisaspire.com/works/lockedDoc> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Work> <http://talisaspire.com/> .\n<http://basedata.com/b/1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Work> <http://talisaspire.com/> .\n<http://basedata.com/b/1> <http://talisaspire.com/schema#seeAlso> <http://talisaspire.com/works/4d101f63c10a6-2> <http://talisaspire.com/> .\n<http://basedata.com/b/2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Work> <http://talisaspire.com/> .\n<http://basedata.com/b/2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://talisaspire.com/schema#Work2> <http://talisaspire.com/> .\n<http://basedata.com/b/2> <http://talisaspire.com/schema#seeAlso> <http://basedata.com/b/1> <http://talisaspire.com/> .\n<tenantUsers:s2123> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://rdfs.org/sioc/spec/User> <http://talisaspire.com/> .\n<tenantUsers:s2123> <http://xmlns.com/foaf/0.1/firstName> \"Harry\" <http://talisaspire.com/> .\n<tenantUsers:s2123> <http://xmlns.com/foaf/0.1/surname> \"Potter\" <http://talisaspire.com/> .\n<tenantUsers:s2123> <http://lists.talis.com/schema/temp#last_login> \"2014-03-25T15:07:12+00:00\" <http://talisaspire.com/> .\n<tenantUsers:s2123> <http://lists.talis.com/schema/temp#last_login_invalid> \"invalid\" <http://talisaspire.com/> .\n<http://basedata.com/b/foo1234> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Document> <http://talisaspire.com/> .\n<http://basedata.com/b/foo1234> <http://purl.org/dc/terms/creator> <http://schemas.talis.com/2005/user/schema#10101> <http://talisaspire.com/> .\n<http://basedata.com/b/foo1234> <http://purl.org/dc/terms/title> \"A document title\" <http://talisaspire.com/> .\n<http://basedata.com/b/foo1234> <http://purl.org/dc/terms/isVersionOf> <http://talisaspire.com/works/4d101f63c10a6> <http://talisaspire.com/> .\n<http://schemas.talis.com/2005/user/schema#10101> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> <http://talisaspire.com/> .\n<http://schemas.talis.com/2005/user/schema#10101> <http://xmlns.com/foaf/0.1/name> \"A. Person\" <http://talisaspire.com/> .\n<http://schemas.talis.com/2005/user/schema#10101> <http://xmlns.com/foaf/0.1/knows> <http://schemas.talis.com/2005/user/schema#10102> <http://talisaspire.com/> .\n<http://schemas.talis.com/2005/user/schema#10102> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> <http://talisaspire.com/> .\n<http://schemas.talis.com/2005/user/schema#10102> <http://xmlns.com/foaf/0.1/name> \"Anne O'ther\" <http://talisaspire.com/> .\n<http://basedata.com/b/bar1234> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/ontology/bibo/Document> <http://talisaspire.com/> .\n<http://basedata.com/b/bar1234> <http://purl.org/dc/terms/creator> <http://schemas.talis.com/2005/user/schema#10103> <http://talisaspire.com/> .\n<http://basedata.com/b/bar1234> <http://purl.org/dc/terms/contributor> <http://schemas.talis.com/2005/user/schema#10101> <http://talisaspire.com/> .\n<http://basedata.com/b/bar1234> <http://purl.org/dc/terms/contributor> <http://schemas.talis.com/2005/user/schema#10102> <http://talisaspire.com/> .\n<http://basedata.com/b/bar1234> <http://purl.org/dc/terms/title> \"Another document title\" <http://talisaspire.com/> .\n<http://basedata.com/b/docWithEmptySeq123> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://basedata.com/b/DocWithSequence> <http://talisaspire.com/> .\n<http://basedata.com/b/docWithEmptySeq123> <http://basedata.com/b/hasSequence> <http://basedata.com/b/sequence123> <http://talisaspire.com/> .\n<http://basedata.com/b/docWithEmptySeq123> <http://purl.org/dc/terms/creator> <http://schemas.talis.com/2005/user/schema#xyz> <http://talisaspire.com/> .\n<http://basedata.com/b/docWithEmptySeq123> <http://purl.org/dc/terms/title> \"Doc with sequence\" <http://talisaspire.com/> ."; $serializer = new NQuadSerializer(); $actual = $serializer->getSerializedIndex($g->_index, \Tripod\Mongo\Config::getInstance()->getDefaultContextAlias()); // This test initially asserted that $expected was equal to $actual // $this->assertEquals($expected, $actual); // However, each time test data was added - it would also need to be added to expected above. // Rather than increasing the size of $expected further when adding new test data // this test now asserts that each line in $expected has been serialised correctly, without failing // due to new test data. foreach (preg_split("/((\r?\n)|(\r\n?))/", $expected) as $expectedLine) { $this->assertTrue(strpos($actual, rtrim($expectedLine)) !== false, "Failed checking for line: " . rtrim($expectedLine)); } }
/** * @param array $query * @param string $type * @param Collection|null $collection * @param array $includeProperties * @param int $cursorSize * @return MongoGraph */ protected function fetchGraph($query, $type, $collection = null, $includeProperties = array(), $cursorSize = 101) { $graph = new MongoGraph(); $t = new \Tripod\Timer(); $t->start(); if ($collection == null) { $collection = $this->collection; $collectionName = $collection->getCollectionName(); } else { $collectionName = $collection->getCollectionName(); } if (empty($includeProperties)) { $cursor = $collection->find($query); } else { $fields = array(); foreach ($includeProperties as $property) { $fields[$this->labeller->uri_to_alias($property)] = true; } $cursor = $collection->find($query, array('projection' => $fields, 'batchSize' => $cursorSize)); } $ttlExpiredResources = false; $retries = 1; $exception = null; $cursorSuccess = false; do { try { foreach ($cursor as $result) { // handle MONGO_VIEWS that have expired due to ttl. These are expired // on read (lazily) rather than on write if ($type == MONGO_VIEW && array_key_exists(_EXPIRES, $result['value'])) { // if expires < current date, regenerate view.. $currentDate = \Tripod\Mongo\DateUtil::getMongoDate(); if ($result['value'][_EXPIRES]->__toString() < $currentDate) { // regenerate! $this->generateView($result['_id']['type'], $result['_id']['r']); } } $graph->add_tripod_array($result); } $cursorSuccess = true; } catch (\Exception $e) { self::getLogger()->error("CursorException attempt " . $retries . ". Retrying...:" . $e->getMessage()); sleep(1); $retries++; $exception = $e; } } while ($retries <= Config::CONNECTION_RETRIES && $cursorSuccess === false); if ($cursorSuccess === false) { self::getLogger()->error("CursorException failed after " . $retries . " attempts (MAX:" . Config::CONNECTION_RETRIES . "): " . $e->getMessage()); throw new \Exception($exception); } if ($ttlExpiredResources) { // generate views and retry... $this->debugLog("One or more view had exceeded TTL was regenerated - request again..."); $graph = $this->fetchGraph($query, $type, $collection); } $t->stop(); $this->timingLog($type, array('duration' => $t->result(), 'query' => $query, 'collection' => $collectionName)); if ($type == MONGO_VIEW) { if (array_key_exists("_id.type", $query)) { $this->getStat()->timer("{$type}.{$query["_id.type"]}", $t->result()); } else { if (array_key_exists("_id", $query) && array_key_exists("type", $query["_id"])) { $this->getStat()->timer("{$type}.{$query["_id"]["type"]}", $t->result()); } } } else { $this->getStat()->timer("{$type}.{$collectionName}", $t->result()); } return $graph; }
/** * @param \Tripod\ChangeSet $cs Change-set to apply * @param string $contextAlias * @throws \Tripod\Exceptions\Exception * @return array An array of subjects and predicates that have been changed */ protected function storeChanges(\Tripod\ChangeSet $cs, $contextAlias) { $t = new \Tripod\Timer(); $t->start(); $subjectsOfChange = $cs->get_subjects_of_change(); $transaction_id = $this->generateTransactionId(); // store the details of the transaction in the transaction log $mongoGraph = new MongoGraph(); $mongoGraph->_index = $cs->_index; $csDoc = $mongoGraph->to_tripod_view_array("changes", $contextAlias); // todo - this changed to tripod view array, why is "changes" the docId? $originalCBDs = array(); // apply the changes try { // 1. lock all documents // 2. create new transaction // 3. apply changes // 4. unlock all documents // 5. complete transaction $originalCBDs = $this->lockAllDocuments($subjectsOfChange, $transaction_id, $contextAlias); $this->getTransactionLog()->createNewTransaction($transaction_id, $csDoc['value'][_GRAPHS], $originalCBDs, $this->getStoreName(), $this->getPodName()); if (empty($originalCBDs)) { $this->getTransactionLog()->failTransaction($transaction_id, new \Exception('Did not obtain locks on documents')); throw new \Exception('Did not obtain locks on documents'); } $changes = $this->applyChangeSet($cs, $originalCBDs, $contextAlias, $transaction_id); $this->debugLog(MONGO_LOCK, array('description' => 'Driver::storeChanges - Unlocking documents, apply change-set completed', 'transaction_id' => $transaction_id)); $this->unlockAllDocuments($transaction_id); $this->getTransactionLog()->completeTransaction($transaction_id, $changes['newCBDs']); $t->stop(); $this->timingLog(MONGO_WRITE, array('duration' => $t->result(), 'subjectsOfChange' => implode(", ", $subjectsOfChange))); $this->getStat()->timer(MONGO_WRITE . ".{$this->getPodName()}", $t->result()); return $changes; } catch (\Exception $e) { $this->getStat()->increment(MONGO_ROLLBACK); $this->errorLog(MONGO_ROLLBACK, array('description' => 'Save Failed Rolling back transaction:' . $e->getMessage(), 'transaction_id' => $transaction_id, 'subjectsOfChange' => implode(",", $subjectsOfChange), 'mongoDriverError' => $this->getLastDBError($this->getDatabase()), 'exceptionMessage' => $e->getMessage())); $this->rollbackTransaction($transaction_id, $originalCBDs, $e); throw new \Tripod\Exceptions\Exception('Error storing changes: ' . $e->getMessage() . " >>>" . $e->getTraceAsString()); } }
/** * @param string $cbdSubject * @param MongoGraph $cbdGraph * @param Collection $collection * @param string $context * @throws \Exception */ protected function saveCBD($cbdSubject, MongoGraph $cbdGraph, Collection $collection, $context) { $cbdSubject = $this->labeller->uri_to_alias($cbdSubject); if ($cbdGraph == null || $cbdGraph->is_empty()) { throw new \Exception("graph for {$cbdSubject} was null"); } try { $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1)); print "."; } catch (\Exception $e) { if (preg_match('/E11000/', $e->getMessage())) { print "M"; // key already exists, merge it $criteria = array("_id" => array("r" => $cbdSubject, "c" => $context)); $existingGraph = new MongoGraph(); $existingGraph->add_tripod_array($collection->findOne($criteria)); $existingGraph->add_graph($cbdGraph); try { $collection->updateOne($criteria, ['$set' => $existingGraph->to_tripod_array($cbdSubject, $context)], array("w" => 1)); } catch (\Exception $e2) { throw new \Exception($e2->getMessage()); // todo: would be good to have typed exception } } else { // retry print "CursorException on update: " . $e->getMessage() . ", retrying\n"; try { $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1)); } catch (\Exception $e2) { throw new \Exception($e2->getMessage()); // todo: would be good to have typed exception } } } }