source: Dev/branches/jQueryUI/rdfapi/sparql/SparqlEngineDb/ResultRenderer/Default.php @ 248

Last change on this file since 248 was 12, checked in by basvannuland, 14 years ago

Added RAP RDF API
Added RDF reader writer for save and load survey

File size: 13.1 KB
Line 
1<?php
2require_once RDFAPI_INCLUDE_DIR . 'sparql/SparqlEngineDb/ResultRenderer.php';
3
4/**
5*   Default RAP result renderer.
6*
7*   @author Christian Weiske <cweiske@cweiske.de>
8*   @license http://www.gnu.org/licenses/lgpl.html LGPL
9*
10*   @package sparql
11*/
12class SparqlEngineDb_ResultRenderer_Default implements SparqlEngineDb_ResultRenderer
13{
14
15    /**
16    *   Defines the methods needed to create the types
17    *   in $arVarAssignments.
18    *   Key is the type (e.g. "s" for subject), and
19    *   value the method's name.
20    *
21    *   @see $arVarAssignments
22    *
23    *   @var array
24    */
25    protected $arCreationMethods = array(
26        's' => 'createSubjectFromDbRecordSetPart',
27        'p' => 'createPredicateFromDbRecordSetPart',
28        'o' => 'createObjectFromDbRecordSetPart'
29    );
30
31
32
33    /**
34    *   Converts the database results into the desired output format
35    *   and returns the result.
36    *
37    *   @param array $arRecordSets  Array of (possibly several) SQL query results.
38    *   @param Query $query     SPARQL query object
39    *   @param SparqlEngineDb $engine   Sparql Engine to query the database
40    *   @return mixed   The result as rendered by the result renderers.
41    */
42    public function convertFromDbResults($arRecordSets, Query $query, SparqlEngineDb $engine)
43    {
44        $this->query    = $query;
45        $this->engine   = $engine;
46        $this->sg       = $engine->getSqlGenerator();
47
48        $strResultForm = $this->query->getResultForm();
49        switch ($strResultForm) {
50            case 'construct':
51            case 'select':
52            case 'select distinct':
53                $arResult = $this->getVariableArrayFromRecordSets($arRecordSets, $strResultForm);
54
55                //some result forms need more modification
56                switch ($strResultForm) {
57                    case 'construct';
58                        $arResult = $this->constructGraph(
59                            $arResult,
60                            $this->query->getConstructPattern()
61                        );
62                        break;
63                    case 'describe';
64                        $arResult = $this->describeGraph($arResult);
65                        break;
66                }
67
68                return $arResult;
69                break;
70
71            case 'count':
72            case 'ask':
73                if (count($arRecordSets) > 1) {
74                    throw new Exception(
75                        'More than one result set for a '
76                        . $strResultForm . ' query!'
77                    );
78                }
79
80                $nCount = 0;
81                $dbRecordSet = reset($arRecordSets);
82                foreach ($dbRecordSet as $row) {
83                    $nCount += intval($row['count']);
84                    break;
85                }
86
87                if ($strResultForm == 'ask') {
88                    return $nCount > 0;
89                } else {
90                    return $nCount;
91                }
92                break;
93
94            case 'describe':
95            default:
96                throw new Exception('Unsupported result form: ' . $strResultForm);
97        }
98
99    }//public function convertFromDbResults($arRecordSets, Query $query, SparqlEngineDb $engine)
100
101
102
103
104    protected function getVariableArrayFromRecordSets($arRecordSets, $strResultForm)
105    {
106        $arResult = array();
107        foreach ($arRecordSets as $dbRecordSet) {
108            $arResult = array_merge(
109                $arResult,
110                $this->getVariableArrayFromRecordSet($dbRecordSet, $strResultForm)
111            );
112        }
113        return $arResult;
114    }//protected function getVariableArrayFromRecordSets($arRecordSets, $strResultForm)
115
116
117
118    /**
119    *   Converts a ADORecordSet object into an array of "rows" that
120    *   are subarrays of variable => value pairs.
121    *
122    *   @param ADORecordSet $dbRecordSet    Anything ADOConnection::Execute() can return
123    *   @return array
124    */
125    protected function getVariableArrayFromRecordSet(ADORecordSet $dbRecordSet, $strResultForm)
126    {
127        $arResult       = array();
128        switch ($strResultForm) {
129            case 'construct':
130                $arResultVars = $this->query->getConstructPatternVariables();
131                break;
132            default:
133                $arResultVars = $this->query->getResultVars();
134                break;
135        }
136
137        if (in_array('*', $arResultVars)) {
138            $arResultVars   = array_keys($this->sg->arVarAssignments);
139        }
140
141        //work around bug in adodb:
142        // ADORecordSet_empty does not implement php5 iterators
143        if ($dbRecordSet->RowCount() <= 0) {
144            return array();
145        }
146
147        foreach ($dbRecordSet as $row) {
148            $arResultRow = array();
149            foreach ($arResultVars as $strVar) {
150                $strVarName = (string)$strVar;
151                if (!isset($this->sg->arVarAssignments[$strVarName])) {
152                    //variable is in select, but not in result (test: q-select-2)
153                    $arResultRow[$strVarName] = '';
154                } else {
155                    $arVarSettings  = $this->sg->arVarAssignments[$strVarName];
156                    $strMethod      = $this->arCreationMethods[$arVarSettings[1]];
157                    $arResultRow[$strVarName] = $this->$strMethod($dbRecordSet, $arVarSettings[0], $strVar);
158                }
159            }
160            $arResult[] = $arResultRow;
161        }
162        return $arResult;
163    }//function getVariableArrayFromRecordSet(ADORecordSet $dbRecordSet)
164
165
166
167    /**
168    *   Creates an RDF Statement object for one of the variables
169    *   contained in the given $dbRecordSet object.
170    *
171    *   @see convertFromDbResult() to understand $strVarBase necessity
172    *
173    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
174    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
175    *
176    *   @return Statement   RDF statement object
177    */
178    protected function createStatementFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase)
179    {
180        return new Statement(
181            $this->createSubjectFromDbRecordSetPart  ($dbRecordSet, $strVarBase),
182            $this->createPredicateFromDbRecordSetPart($dbRecordSet, $strVarBase),
183            $this->createObjectFromDbRecordSetPart   ($dbRecordSet, $strVarBase)
184        );
185    }//protected function createStatementFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase)
186
187
188
189    /**
190    *   Creates an RDF subject object
191    *   contained in the given $dbRecordSet object.
192    *
193    *   @see convertFromDbResult() to understand $strVarBase necessity
194    *
195    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
196    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
197    *
198    *   @return Resource   RDF triple subject resource object
199    */
200    protected function createSubjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
201    {
202        $strVarName = (string)$strVar;
203        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
204            //FIXME: should be NULL, but doesn't pass test
205            return '';
206        }
207
208        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']] == 'r'
209            //null should be predicate which is always a resource
210         || $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']] === null
211        ) {
212            $subject    = new Resource ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
213        } else {
214            $subject    = new BlankNode($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
215        }
216        return $subject;
217    }//protected function createSubjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVarName)
218
219
220
221    /**
222    *   Creates an RDF predicate object
223    *   contained in the given $dbRecordSet object.
224    *
225    *   @see convertFromDbResult() to understand $strVarBase necessity
226    *
227    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
228    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
229    *
230    *   @return Resource   RDF triple predicate resource object
231    */
232    protected function createPredicateFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
233    {
234        $strVarName = (string)$strVar;
235        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
236            //FIXME: should be NULL, but doesn't pass test
237            return '';
238        }
239        $predicate      = new Resource ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
240        return $predicate;
241    }//protected function createPredicateFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVarName)
242
243
244
245    /**
246    *   Creates an RDF object object
247    *   contained in the given $dbRecordSet object.
248    *
249    *   @see convertFromDbResult() to understand $strVarBase necessity
250    *
251    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
252    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
253    *
254    *   @return Resource   RDF triple object resource object
255    */
256    protected function createObjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
257    {
258        $strVarName = (string)$strVar;
259        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
260            //FIXME: should be NULL, but doesn't pass test
261            return '';
262        }
263        switch ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']]) {
264            case 'r':
265                $object = new Resource ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
266                break;
267            case 'b':
268                $object = new BlankNode($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
269                break;
270            default:
271                $object = new Literal(
272                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']],
273                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_lang']]
274                );
275                if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_type']]) {
276                    $object->setDatatype($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_type']]);
277                }
278        }
279        return $object;
280    }//protected function createObjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVarName)
281
282
283
284    /**
285    * Constructs a result graph.
286    *
287    * @param  array         $arVartable       A table containing the result vars and their bindings
288    * @param  GraphPattern  $constructPattern The CONSTRUCT pattern
289    * @return MemModel      The result graph which matches the CONSTRUCT pattern
290    */
291    protected function constructGraph($arVartable, $constructPattern)
292    {
293        $resultGraph = new MemModel();
294
295        if (!$arVartable) {
296            return $resultGraph;
297        }
298
299        $tp = $constructPattern->getTriplePatterns();
300
301        $bnode = 0;
302        foreach ($arVartable as $value) {
303            foreach ($tp as $triple) {
304                $sub  = $triple->getSubject();
305                $pred = $triple->getPredicate();
306                $obj  = $triple->getObject();
307
308                if (is_string($sub)  && $sub{1} == '_') {
309                    $sub  = new BlankNode("_bN".$bnode);
310                }
311                if (is_string($pred) && $pred{1} == '_') {
312                    $pred = new BlankNode("_bN".$bnode);
313                }
314                if (is_string($obj)  && $obj{1} == '_') {
315                    $obj  = new BlankNode("_bN".$bnode);
316                }
317
318
319                if (is_string($sub)) {
320                    $sub  = $value[$sub];
321                }
322                if (is_string($pred)) {
323                    $pred = $value[$pred];
324                }
325                if (is_string($obj)) {
326                    $obj  = $value[$obj];
327                }
328
329                if ($sub !== "" && $pred !== "" && $obj !== "") {
330                    $resultGraph->add(new Statement($sub,$pred,$obj));
331                }
332            }
333            $bnode++;
334        }
335        return $resultGraph;
336    }//protected function constructGraph($arVartable, $constructPattern)
337
338}//class SparqlEngineDb_ResultRenderer_Default implements SparqlEngineDb_ResultRenderer
339?>
Note: See TracBrowser for help on using the repository browser.