User:Woozle/smw-base-v2.php

Code
<?php /* **** FILE: smw-base-v2.php PURPOSE: Semantic MediaWiki interface classes for SMW schema version 2 I'm calling it version 2 (instead of version 1) because there's evidence of at least one prior db schema version. It seems to apply to SMW versions prior to 1.18 or possibly 1.19. I will probably not be maintaining it any further. REQUIRES: data.php TODO: this goes directly to the DatabaseMysql class for some functions; needs to be generalized to use abstract wrappers. HISTORY: 2012-01-22 started 2012-09-17 useful pieces working 2013-01-24 moved clsMWData and clsDataResult_MW from to mw-base.php /*==== PURPOSE: version-2-specific class methods for clsSMWData class clsSMWData_version extends clsMWData { /*     RETURNS: array of pages where the given property has the given value (or, if iPropValue is left out, just having the given property) INPUT: $iarFilt is an array of properties and value restrictions, all of which must be met [property name] => value filter value filter should be a comparison, e.g. >0 or ="things" RETURNS: array of rows\ arrays USED BY: psycrit.w3f_Show_Response_Header HISTORY: 2012-11-01 revised to look up SMW ID first, reducing CPU. Return array format has SMW ID as key. */   public function GetPages_forPropVal($iPropName,$iPropValue) {

// look up property's SMW ID	$sqlProp = SQLValue(static::NormalizeTitle($iPropName,SMW_NS_PROPERTY)); $sql = "SELECT smw_id FROM smw_ids WHERE (smw_title=$sqlProp) LIMIT 1;"; $rs = $this->DataSet($sql); if ($rs->HasRows) { $rs->NextRow;	// should be only one row -- get it. $idProp = $rs->Value('smw_id'); } else { // TODO: some kind of indication that the property does not seem to even exist }

// look up value's SMW ID (TODO: this is not always applicable) $sqlVal = SQLValue(static::NormalizeTitle($iPropValue,SMW_NS_PROPERTY)); $sql = "SELECT smw_id FROM smw_ids WHERE (smw_title=$sqlVal) LIMIT 1;"; $rs = $this->DataSet($sql); if ($rs->HasRows) { $rs->NextRow;	// should be only one row -- get it. $idVal = $rs->Value('smw_id'); } else { // TODO: some kind of indication that the value does not seem to even exist throw new exception('No rows returned for query "'.$sql.'"'); }	// find all pages where that property is set

// start with smw_rels2, which is properties that are titles (the default kind of property) // there are probably other tables we need to check, but this will do for immediate needs.

$sql = 'SELECT s_id,' .' s.smw_namespace AS s_namespace' .', CAST(s.smw_title AS char) AS s_title' //.', CAST(p.smw_title AS char) AS p_title' //.', CAST(o.smw_title AS char) AS o_title' .' FROM' .' (smw_rels2 AS r'	   .' LEFT JOIN smw_ids AS s ON r.s_id=s.smw_id)' //.' LEFT JOIN smw_ids AS p ON r.p_id=p.smw_id)'	   .' LEFT JOIN smw_ids AS o ON r.o_id=o.smw_id'	  ." WHERE (o_id=$idVal) AND (p_id=$idProp);";	$rs = $this->DataSet($sql);	if ($rs->HasRows) {	    $arOut = array;	    while ($rs->NextRow) {		$idPage = $rs->Value('s_id');		$arOut[$idPage] = $rs->Values;	    }	    return $arOut;	} else {	    // TODO: some kind of indication that the property was found but no pages matched	    return NULL;	// nothing found	}    }    public function GetPages_forPropVal_OLD($iPropName,$iPropValue) {	$arOut = NULL;

// 1. check RELS

$sql = 'SELECT' //	 .' r.s_id,' .' s.smw_title AS page_name,'		// needed for output .' s.smw_namespace AS page_space,'	// needed for output //	 .' p.smw_title AS prop_name,'	// needed for filter //	 .' o.smw_title AS prop_val,'	// needed for filter .' s.smw_namespace' .' FROM ((smw_rels2 AS r'	 .' LEFT JOIN smw_ids AS s ON r.s_id=s.smw_id)'	  .' LEFT JOIN smw_ids AS p ON r.p_id=p.smw_id)' .' LEFT JOIN smw_ids AS o ON r.o_id=o.smw_id' .' WHERE (p.smw_title="'.$iPropName.'") AND (o.smw_title="'.$iPropValue.'");';

$rs = $this->DataSet($sql); if ($rs->HasRows) { while ($rs->NextRow) { $objTitle = new w3smwPage($this); $objTitle->Use_Title_Keyed($rs->Value('page_name'),$rs->Value('page_space')); $arOut[] = $objTitle; }	}

// 2. check ATTS $sql = 'SELECT' //	 .' a.s_id,' .' s.smw_title AS page_name,'		// needed for output .' s.smw_namespace AS page_space,'	// needed for output //	 .' p.smw_title AS prop_name,'	// needed for filter //	 .' value_xsd AS prop_val,'	// needed for filter .' value_num'	// might be used later for filter .' FROM (smw_atts2 AS a'	 .' LEFT JOIN smw_ids AS s ON a.s_id=s.smw_id)' .' LEFT JOIN smw_ids AS p ON a.p_id=p.smw_id' .' WHERE (p.smw_title="'.$iPropName.'") AND (value_xsd="'.$iPropValue.'");';

$rs = $this->DataSet($sql); if ($rs->HasRows) { while ($rs->NextRow) { $objTitle = new w3smwPage($this); $objTitle->Use_Title_Keyed($rs->Value('page_name'),$rs->Value('page_space')); $arOut[] = $objTitle; }	}

return $arOut; }   /*      INPUT: $iarFilt is an array of properties and value restrictions, all of which must be met [property name] => value filter value filter should be a comparison, e.g. >0 or ="things" WHO USES THIS? I don't think this ever actually worked, but keep it until certain. */   public function GetPages_forProps_BAD(array $iarFilt) { $sqlFilt = ''; // convert filter into the format MediaWiki's Database class needs: foreach ($iarFilt as $fld => $req) { if ($sqlFilt != '') { $sqlFilt .= ' AND'; }	   $sqlFilt .= " ('$fld'$req)"; }

$sql = 'SELECT ip.smw_title AS PropName, it.smw_namespace AS PageSpace, it.smw_title AS PageName, t.value_blob AS Value' .' FROM (smw_text2 AS t'	 .' LEFT JOIN smw_ids AS ip ON t.p_id=ip.smw_id)' .' LEFT JOIN smw_ids AS it ON t.s_id=it.smw_id' .' WHERE'.$sqlFilt .' ORDER BY ip.smw_sortkey, it.smw_sortkey';

// in the future we can use the more operation-specific Database methods, but for now this is simpler: $rs = $this->DataSet($sql); return $rs; } }

class w3smwPage_version { /*     TODO: * Translate special properties such as "Date" -> "_dat". Is there a formal list somewhere? Do we have to always check all three tables, or can we assume that if a value is found in one table, it isn't in the others? */   public function GetPropData($iPropName) { $strPageKey = $this->TitleKey; $strPropKey = Title::capitalize($iPropName,SMW_NS_PROPERTY); $sqlPageKey = $this->Engine->SafeParam($strPageKey); $sqlPropKey = $this->Engine->SafeParam($strPropKey);

$intNSpace = (int)$this->Nspace;

// PART ONE: smw_atts2 $sql = 'SELECT value_xsd, value_num' .' FROM (smw_atts2 AS a'	 .' LEFT JOIN smw_ids AS s ON a.s_id=s.smw_id)' .' LEFT JOIN smw_ids AS p ON a.p_id=p.smw_id' .' WHERE' ." (p.smw_title = '$sqlPropKey') AND" ." (s.smw_title = '$sqlPageKey') AND" ." (s.smw_namespace = $intNSpace);"; $rs = $this->Engine->DataSet($sql); $arOut['atts'] = $rs;

// PART TWO: smw_rels2 $sql = 'SELECT' .' r.*,' .' CAST(s.smw_title AS char) AS s_title,' .' CAST(p.smw_title AS char) AS p_title,' .' CAST(o.smw_title AS char) AS o_title' .' FROM' .' ((smw_rels2 AS r'	 .' LEFT JOIN smw_ids AS s ON r.s_id=s.smw_id)'	  .' LEFT JOIN smw_ids AS p ON r.p_id=p.smw_id)' .' LEFT JOIN smw_ids AS o ON r.o_id=o.smw_id' .' WHERE' ." (p.smw_title = '$sqlPropKey') AND" ." (s.smw_title = '$sqlPageKey') AND" ." (s.smw_namespace = $intNSpace);"; $rs = $this->Engine->DataSet($sql); $arOut['rels'] = $rs;

// PART THREE: smw_text2 $sql = 'SELECT' .' s_id,' .' p_id,' .' CAST(s.smw_title AS CHAR) AS s_title,' .' CAST(p.smw_title AS CHAR) AS p_title,' .' CAST(value_blob AS CHAR) AS value' .' FROM (smw_text2 AS t'	 .' LEFT JOIN smw_ids AS s ON t.s_id=s.smw_id)' .' LEFT JOIN smw_ids AS p ON t.p_id=p.smw_id' .' WHERE' ." (p.smw_title = '$sqlPropKey') AND" ." (s.smw_title = '$sqlPageKey') AND" ." (s.smw_namespace = $intNSpace);"; $rs = $this->Engine->DataSet($sql); $arOut['text'] = $rs; return $arOut; }   /*      RETURNS: array[smw_id] = value ASSUMES: smw_sortkey is the non-underscored version of smw_title USAGE: when multiple values are expected to happen sometimes */   public function GetPropVals($iPropName) { $ar = $this->GetPropData($iPropName);

$out = NULL; $idx = 0;

// first check ATTS $rs = $ar['atts']; if ($rs->HasRows) { while ($rs->NextRow) { $idx++; $strVal = $rs->Value('value_xsd'); $out[$idx] = $strVal; }	}

// next check RELS $rs = $ar['rels']; if ($rs->HasRows) { while ($rs->NextRow) { $idx++; $strVal = $rs->Value('o_title'); $out[$idx] = clsSMWData::VisualizeTitle($strVal); }	}

// next check TEXT $rs = $ar['text']; if ($rs->HasRows) { while ($rs->NextRow) { $idx++; $strVal = $rs->Value('value'); $out[$idx] = $strVal; }	}

return $out; } }

class tblSMW_PageProps extends clsTable_indexed { public function __construct($iDB) { parent::__construct($iDB); $this->Name('smw_text2'); $this->ClassSng('rcSMW_PageProp'); } }