source: Dev/trunk/rdfapi/sparql/SparqlEngineDb/ResultRenderer/PlainText.php @ 12

Last change on this file since 12 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.2 KB
Line 
1<?php
2require_once RDFAPI_INCLUDE_DIR . 'sparql/SparqlEngineDb/ResultRenderer.php';
3
4/**
5*   Result renderer that creates a text array
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_PlainText 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            return $this->createResource($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
213        } else {
214            return $this->createBlankNode($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
215        }
216        return $subject;
217    }//protected function createSubjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
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        return $this->createResource($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
240    }//protected function createPredicateFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
241
242
243
244    /**
245    *   Creates an RDF object object
246    *   contained in the given $dbRecordSet object.
247    *
248    *   @see convertFromDbResult() to understand $strVarBase necessity
249    *
250    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
251    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
252    *
253    *   @return Resource   RDF triple object resource object
254    */
255    protected function createObjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
256    {
257        $strVarName = (string)$strVar;
258        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
259            //FIXME: should be NULL, but doesn't pass test
260            return '';
261        }
262        switch ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']]) {
263            case 'r':
264                return $this->createResource($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
265                break;
266            case 'b':
267                return $this->createBlankNode($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
268                break;
269            default:
270                return $this->createLiteral(
271                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']],
272                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_lang']],
273                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_type']]
274                );
275        }
276    }//protected function createObjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
277
278
279
280    /**
281    * Constructs a result graph.
282    *
283    * @param  array         $arVartable       A table containing the result vars and their bindings
284    * @param  GraphPattern  $constructPattern The CONSTRUCT pattern
285    * @return MemModel      The result graph which matches the CONSTRUCT pattern
286    */
287    protected function constructGraph($arVartable, $constructPattern)
288    {
289        $resultGraph = new MemModel();
290
291        if (!$arVartable) {
292            return $resultGraph;
293        }
294
295        $tp = $constructPattern->getTriplePatterns();
296
297        $bnode = 0;
298        foreach ($arVartable as $value) {
299            foreach ($tp as $triple) {
300                $sub  = $triple->getSubject();
301                $pred = $triple->getPredicate();
302                $obj  = $triple->getObject();
303
304                if (is_string($sub)  && $sub{1} == '_') {
305                    $sub  = new BlankNode("_bN".$bnode);
306                }
307                if (is_string($pred) && $pred{1} == '_') {
308                    $pred = new BlankNode("_bN".$bnode);
309                }
310                if (is_string($obj)  && $obj{1} == '_') {
311                    $obj  = new BlankNode("_bN".$bnode);
312                }
313
314
315                if (is_string($sub)) {
316                    $sub  = $value[$sub];
317                }
318                if (is_string($pred)) {
319                    $pred = $value[$pred];
320                }
321                if (is_string($obj)) {
322                    $obj  = $value[$obj];
323                }
324
325                if ($sub !== "" && $pred !== "" && $obj !== "") {
326                    $resultGraph->add(new Statement($sub,$pred,$obj));
327                }
328            }
329            $bnode++;
330        }
331        return $resultGraph;
332    }//protected function constructGraph($arVartable, $constructPattern)
333
334
335
336    protected function createResource($uri)
337    {
338        return 'R<' . $uri . '>';
339    }//protected function createResource($uri)
340
341
342
343    protected function createBlankNode($id)
344    {
345        return 'B(' . $id . ')';
346    }//protected function createBlankNode($id)
347
348
349
350    protected function createLiteral($value, $language, $datatype)
351    {
352        $v = 'L(' . $value;
353        if ($language != null) {
354            $v .= '@' . $language;
355        }
356        if ($datatype != null) {
357            $v .= '^^' . $datatype;
358        }
359        return $v . ')';
360    }//protected function createLiteral($value, $language, $datatype)
361
362}//class SparqlEngineDb_ResultRenderer_PlainText implements SparqlEngineDb_ResultRenderer
363?>
Note: See TracBrowser for help on using the repository browser.