/** * Does update. First deletes, then inserts. * @param $data */ function updateData(SMWSemanticData $data) { $export = SMWExporter::makeExportData($data); // let other extensions add additional RDF data for this page (i.e. Semantic Internal Objects) //this code is based on the modifications made on SemanticMediaWiki/includes/export/SMW_OWLExport.php $additionalDataArray = array(); $fullexport = true; $backlinks = false; wfRunHooks('smwAddToRDFExport', array($data->getSubject()->getTitle(), &$additionalDataArray, $fullexport, $backlinks)); $addStatements = array(); foreach ($additionalDataArray as $additionalData) { //add new data associated with internal objects $addStatements = $this->createStatements($additionalData->getTripleList()); } $subject_uri = SMWExporter::expandURI($export->getSubject()->getName()); $this->removeDataForURI($subject_uri); $triple_list = $export->getTripleList(); $addStatements = array_merge($addStatements, $this->createStatements($export->getTripleList())); // create a transaction to execute the updates $statements = array('add' => $addStatements); $transaction = $this->createTransaction($statements); $response = $this->sendTransaction($transaction); //can the delete and insert statements be combined, or will this lead to concurrency issues? return parent::updateData($data); }
/** * Does update. First deletes, then inserts. * @param $data */ function updateData(SMWSemanticData $data) { $export = SMWExporter::makeExportData($data); $sparqlDeleteText = ""; $sparqlUpdateText = "INSERT DATA {\n"; // let other extensions add additional RDF data for this page (i.e. Semantic Internal Objects) //this code is based on the modifications made on SemanticMediaWiki/includes/export/SMW_OWLExport.php $additionalDataArray = array(); $fullexport = true; $backlinks = false; wfRunHooks('smwAddToRDFExport', array($data->getSubject()->getTitle(), &$additionalDataArray, $fullexport, $backlinks)); // this writes update text for each of the Semantic Internal Objects foreach ($additionalDataArray as $additionalData) { $subject_uri = SMWExporter::expandURI($additionalData->getSubject()->getName()); // remove subject from triple store $sparqlDeleteText .= $this->writeDeleteText($subject_uri); //add new data associated with internal objects $sparqlUpdateText .= $this->writeUpdateText($additionalData->getTripleList()); } $subject_uri = SMWExporter::expandURI($export->getSubject()->getName()); // remove subject from triple store $sparqlDeleteText .= $this->writeDeleteText($subject_uri); $triple_list = $export->getTripleList(); $sparqlUpdateText .= $this->writeUpdateText($triple_list); $sparqlUpdateText .= "}"; //delete the old triples wfDebugLog('SPARQL_LOG', "#===DELETE===\n" . $sparqlDeleteText); $response = $this->do_joseki_post($sparqlDeleteText); //insert the new triples wfDebugLog('SPARQL_LOG', "#===INSERT===\n" . $sparqlUpdateText); $response = $this->do_joseki_post($sparqlUpdateText); //can the delete and insert statements be combined, or will this lead to concurrency issues? return parent::updateData($data); }
/** * Does update. First deletes, then inserts. * @param $data */ function updateData( SMWSemanticData $data ) { $export = SMWExporter::makeExportData( $data ); $subject_uri = SMWExporter::expandURI( $export->getSubject()->getUri() ); // remove subject from triple store $this->removeDataForURI( $subject_uri ); $triple_list = $export->getTripleList(); $sparqlUpdateText = "INSERT INTO <> {\n"; foreach ( $triple_list as $triple ) { $subject = $triple[0]; $predicate = $triple[1]; $object = $triple[2]; $obj_str = ""; $sub_str = ""; $pre_str = ""; if ( $object instanceof SMWExpLiteral ) { // @todo FIXME: Add escaping for results of getLexicalForm()? $obj_str = "\"" . $object->getLexicalForm() . "\"" . ( ( $object->getDatatype() == "" ) ? "" : "^^<" . $object->getDatatype() . ">" ); } elseif ( $object instanceof SMWExpResource ) { $obj_str = "<" . SMWExporter::expandURI( $object->getUri() ) . ">"; } else { $obj_str = "\"\""; } if ( $subject instanceof SMWExpResource ) { $sub_str = "<" . SMWExporter::expandURI( $subject->getUri() ) . ">"; } if ( $predicate instanceof SMWExpResource ) { $pre_str = "<" . SMWExporter::expandURI( $predicate->getUri() ) . ">"; } $sparqlUpdateText .= $sub_str . " " . $pre_str . " " . $obj_str . " .\n"; } $sparqlUpdateText .= "}\n"; // echo "<p style='background: #ccddff'><pre>SPARQL Update text:" . $this->unhtmlify( $sparqlUpdateText ) . " ... tjohoo</pre></p>"; // var_dump(); // TODO Debug-code wfDebugLog( 'SPARQL_LOG', "===INSERT===\n" . $sparqlUpdateText ); $response = $this->do_arc2_query( $sparqlUpdateText ); return parent::updateData( $data ); }
static function createRDF($title, $rdfDataArray, $fullexport = true, $backlinks = false) { // if it's not a full export, don't add internal object data if (!$fullexport) { return true; } $pageName = $title->getDBkey(); $namespace = $title->getNamespace(); // Go through all SIOs for the current page, create RDF for // each one, and add it to the general array. $iw = ''; $db = wfGetDB(DB_SLAVE); $res = $db->select('smw_ids', array('smw_id', 'smw_namespace', 'smw_title'), 'smw_title LIKE ' . $db->addQuotes($pageName . '#%') . ' AND ' . 'smw_namespace=' . $db->addQuotes($namespace) . ' AND smw_iw=' . $db->addQuotes($iw), 'SIO::getSMWPageObjectIDs'); while ($row = $db->fetchObject($res)) { $value = new SIOInternalObjectValue($row->smw_title, intval($row->smw_namespace)); if (class_exists('SMWSqlStubSemanticData')) { // SMW >= 1.6 $semdata = new SMWSqlStubSemanticData($value, false); } else { $semdata = new SMWSemanticData($value, false); } $propertyTables = SMWSQLStore2::getPropertyTables(); foreach ($propertyTables as $tableName => $propertyTable) { $data = smwfGetStore()->fetchSemanticData($row->smw_id, null, $propertyTable); foreach ($data as $d) { $semdata->addPropertyStubValue(reset($d), end($d)); } } $rdfDataArray[] = SMWExporter::makeExportData($semdata, null); } return true; }
/** * Serialize data associated to a specific page. This method works on the * level of pages, i.e. it serialises parts of SMW content and implements * features like recursive export or backlinks that are available for this * type of data. * * The recursion depth means the following. Depth of 1 or above means * the object is serialised with all property values, and referenced * objects are serialised with depth reduced by 1. Depth 0 means that only * minimal declarations are serialised, so no dependencies are added. A * depth of -1 encodes "infinite" depth, i.e. a complete recursive * serialisation without limit. * * @param SMWDIWikiPage $diWikiPage specifying the page to be exported * @param integer $recursiondepth specifying the depth of recursion */ protected function serializePage(SMWDIWikiPage $diWikiPage, $recursiondepth = 1) { if ($this->isPageDone($diWikiPage, $recursiondepth)) { return; // do not export twice } $this->markPageAsDone($diWikiPage, $recursiondepth); $semData = $this->getSemanticData($diWikiPage, $recursiondepth == 0); if ($semData === null || $diWikiPage->getDBKey() === '') { return null; } $expData = SMWExporter::makeExportData($semData); $this->serializer->serializeExpData($expData, $recursiondepth); foreach ($semData->getSubSemanticData() as $subobjectSemData) { $this->serializer->serializeExpData(SMWExporter::makeExportData($subobjectSemData)); } // let other extensions add additional RDF data for this page $additionalDataArray = array(); wfRunHooks('smwAddToRDFExport', array($diWikiPage, &$additionalDataArray, $recursiondepth != 0, $this->add_backlinks)); foreach ($additionalDataArray as $additionalData) { $this->serializer->serializeExpData($additionalData); // serialise } if ($recursiondepth != 0) { $subrecdepth = $recursiondepth > 0 ? $recursiondepth - 1 : ($recursiondepth == 0 ? 0 : -1); foreach ($expData->getProperties() as $property) { if ($property->getDataItem() instanceof SMWWikiPageValue) { $this->queuePage($property->getDataItem(), 0); // no real recursion along properties } $wikipagevalues = false; foreach ($expData->getValues($property) as $valueExpElement) { $valueResource = $valueExpElement instanceof SMWExpData ? $valueExpElement->getSubject() : $valueExpElement; if (!$wikipagevalues && $valueResource->getDataItem() instanceof SMWWikiPageValue) { $wikipagevalues = true; } elseif (!$wikipagevalues) { break; } $this->queuePage($valueResource->getDataItem(), $subrecdepth); } } // Add backlinks: // Note: Backlinks are different from recursive serialisations, since // stub declarations (recdepth==0) still need to have the property that // links back to the object. So objects that would be exported with // recdepth 0 cannot be put into the main queue but must be done right // away. They also might be required many times, if they link back to // many different objects in many ways (we cannot consider them "Done" // if they were serialised at recdepth 0 only). if ($this->add_backlinks) { $inprops = \SMW\StoreFactory::getStore()->getInProperties($diWikiPage); foreach ($inprops as $inprop) { $propWikiPage = $inprop->getDiWikiPage(); if (!is_null($propWikiPage)) { $this->queuePage($propWikiPage, 0); // no real recursion along properties } $inSubs = \SMW\StoreFactory::getStore()->getPropertySubjects($inprop, $diWikiPage); foreach ($inSubs as $inSub) { if (!$this->isPageDone($inSub, $subrecdepth)) { $semdata = $this->getSemanticData($inSub, true); if (!$semdata instanceof SMWSemanticData) { continue; } $semdata->addPropertyObjectValue($inprop, $diWikiPage); $expData = SMWExporter::makeExportData($semdata); $this->serializer->serializeExpData($expData, $subrecdepth); } } } if (NS_CATEGORY === $diWikiPage->getNamespace()) { // also print elements of categories $options = new SMWRequestOptions(); $options->limit = 100; // Categories can be large, always use limit $instances = \SMW\StoreFactory::getStore()->getPropertySubjects(new SMWDIProperty('_INST'), $diWikiPage, $options); $pinst = new SMWDIProperty('_INST'); foreach ($instances as $instance) { if (!array_key_exists($instance->getHash(), $this->element_done)) { $semdata = $this->getSemanticData($instance, true); if (!$semdata instanceof SMWSemanticData) { continue; } $semdata->addPropertyObjectValue($pinst, $diWikiPage); $expData = SMWExporter::makeExportData($semdata); $this->serializer->serializeExpData($expData, $subrecdepth); } } } elseif (SMW_NS_CONCEPT === $diWikiPage->getNamespace()) { // print concept members (slightly different code) $desc = new SMWConceptDescription($diWikiPage); $desc->addPrintRequest(new SMWPrintRequest(SMWPrintRequest::PRINT_THIS, '')); $query = new SMWQuery($desc); $query->setLimit(100); $res = \SMW\StoreFactory::getStore()->getQueryResult($query); $resarray = $res->getNext(); $pinst = new SMWDIProperty('_INST'); while ($resarray !== false) { $instance = end($resarray)->getNextDataItem(); if (!array_key_exists($instance->getHash(), $this->element_done)) { $semdata = $this->getSemanticData($instance, true); $semdata->addPropertyObjectValue($pinst, $diWikiPage); $expData = SMWExporter::makeExportData($semdata); $this->serializer->serializeExpData($expData); } $resarray = $res->getNext(); } } } } }
/** * Prepare an array of SMWExpData elements that should be written to * the SPARQL store. The result is empty if no updates should be done. * Note that this is different from writing an SMWExpData element that * has no content. * Otherwise, the first SMWExpData object in the array is a translation * of the given input data, but with redirects resolved. Further * SMWExpData objects might be included in the resulting list to * capture necessary stub declarations for objects that do not have * any data in the RDF store yet. * * @since 1.6 * @param $data SMWSemanticData object containing the update data * @return array of SMWExpData */ protected function prepareUpdateExpData(SMWSemanticData $data) { $expData = SMWExporter::makeExportData($data); $result = array(); $newExpData = $this->expandUpdateExpData($expData, $result, false); array_unshift($result, $newExpData); return $result; }
public function testExportSubSemanticData() { $semanticData = $this->semanticDataFactory->newEmptySemanticData(__METHOD__); $factsheet = $this->fixturesProvider->getFactsheet('berlin'); $factsheet->setTargetSubject($semanticData->getSubject()); $demographicsSubobject = $factsheet->getDemographics(); $semanticData->addPropertyObjectValue($demographicsSubobject->getProperty(), $demographicsSubobject->getContainer()); $exportData = Exporter::makeExportData($semanticData->findSubSemanticData($demographicsSubobject->getSubobjectId())); $this->assertCount(1, $exportData->getValues(Exporter::getSpecialPropertyResource('_SKEY'))); $this->assertCount(1, $exportData->getValues(Exporter::getSpecialNsResource('swivt', 'wikiNamespace'))); }