1+ <?php
2+
3+ /**
4+ * JSONDB - JSON Database Manager
5+ *
6+ * Manage local databases with JSON files and JSON Query Language (JQL)
7+ *
8+ * This content is released under the MIT License (MIT)
9+ *
10+ * Copyright (c) 2016, Centers Technologies
11+ *
12+ * Permission is hereby granted, free of charge, to any person obtaining a copy
13+ * of this software and associated documentation files (the "Software"), to deal
14+ * in the Software without restriction, including without limitation the rights
15+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+ * copies of the Software, and to permit persons to whom the Software is
17+ * furnished to do so, subject to the following conditions:
18+ *
19+ * The above copyright notice and this permission notice shall be included in
20+ * all copies or substantial portions of the Software.
21+ *
22+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+ * THE SOFTWARE.
29+ *
30+ * @package JSONDB
31+ * @author Nana Axel
32+ * @copyright Copyright (c) 2016, Centers Technologies
33+ * @license http://opensource.org/licenses/MIT MIT License
34+ * @filesource
35+ */
36+
37+ namespace JSONDB ;
38+
39+ /**
40+ * Class QueryResult
41+ *
42+ * @package JSONDB
43+ * @subpackage Utilities
44+ * @category Results
45+ * @author Nana Axel
46+ */
47+ class QueryResult implements \Iterator, \SeekableIterator, \Countable, \Serializable, \ArrayAccess
48+ {
49+ /**
50+ * Current key
51+ * @var string|int
52+ */
53+ private $ key = 0 ;
54+
55+ /**
56+ * Results array
57+ * @var array
58+ */
59+ private $ results ;
60+
61+ /**
62+ * Fetch mode
63+ * @var int
64+ */
65+ private $ fetchMode ;
66+
67+ /**
68+ * JSONDB instance
69+ * @var JSONDB
70+ */
71+ private $ database ;
72+
73+ /**
74+ * QueryResult __constructor
75+ * @param array $result
76+ * @param JSONDB $database The JSONDB instance to use with results.
77+ */
78+ public function __construct (array $ result , JSONDB $ database )
79+ {
80+ $ this ->database = $ database ;
81+ $ this ->_setResults ($ result );
82+ $ this ->_parseResults ();
83+ }
84+
85+ /**
86+ * Changes the value of results
87+ * @param mixed $results
88+ */
89+ private function _setResults ($ results )
90+ {
91+ $ this ->results = $ results ;
92+ }
93+
94+ /**
95+ * Checks if the key can be accessed
96+ */
97+ public function valid ()
98+ {
99+ if ($ this ->key === '#queryString ' ) {
100+ return FALSE ;
101+ } else {
102+ return array_key_exists ($ this ->key , $ this ->results );
103+ }
104+ }
105+
106+ /**
107+ * Returns the current result
108+ * @return array
109+ */
110+ public function current ()
111+ {
112+ return $ this ->results [$ this ->key ];
113+ }
114+
115+ /**
116+ * Seeks the internal pointer to the next value
117+ */
118+ public function next ()
119+ {
120+ $ this ->key ++;
121+ }
122+
123+ /**
124+ * Returns the value of the internal pointer
125+ * @return mixed
126+ */
127+ public function key ()
128+ {
129+ return $ this ->key ;
130+ }
131+
132+ /**
133+ * Seeks the internal pointer to 0
134+ */
135+ public function rewind ()
136+ {
137+ $ this ->key = 0 ;
138+ }
139+
140+ /**
141+ * Seeks the internal pointer to a position
142+ * @param int $position
143+ * @throws Exception
144+ * @return mixed
145+ */
146+ public function seek ($ position )
147+ {
148+ $ lastKey = $ this ->key ;
149+ $ this ->key = $ position ;
150+
151+ if (!$ this ->valid ()) {
152+ $ this ->key = $ lastKey ;
153+ throw new Exception ("JSONDB Query Result Error: Trying to access an inexisting result key \"{$ position }\"" );
154+ }
155+ }
156+
157+ /**
158+ * Counts results
159+ * @return int
160+ */
161+ public function count ()
162+ {
163+ $ counter = 0 ;
164+ foreach ((array )$ this ->results as $ key => $ value ) {
165+ if (is_int ($ key )) {
166+ ++$ counter ;
167+ }
168+ }
169+
170+ return $ counter ;
171+ }
172+
173+ /**
174+ * Serializes results
175+ * @return string
176+ */
177+ public function serialize ()
178+ {
179+ return serialize ($ this ->results );
180+ }
181+
182+ /**
183+ * Unserializes results
184+ * @param string $serialized
185+ * @return QueryResult
186+ */
187+ public function unserialize ($ serialized )
188+ {
189+ $ this ->_setResults (unserialize ($ serialized ));
190+ return $ this ;
191+ }
192+
193+ /**
194+ * Checks if a result exist at the given offset
195+ * @param int $offset
196+ * @return bool
197+ */
198+ public function offsetExists ($ offset )
199+ {
200+ return array_key_exists ($ offset , $ this ->results );
201+ }
202+
203+ /**
204+ * Return the result at the given offset
205+ * @param int $offset
206+ * @return mixed
207+ * @throws Exception
208+ */
209+ public function offsetGet ($ offset )
210+ {
211+ if ($ this ->offsetExists ($ offset )) {
212+ return $ this ->results [$ offset ];
213+ } else {
214+ throw new Exception ("JSONDB Query Result Error: Can't access the result at offset \"{$ offset }\". " );
215+ }
216+ }
217+
218+ /**
219+ * Changes the result value at the given offset
220+ * @param int $offset
221+ * @param array $value
222+ * @return void
223+ * @throws Exception
224+ */
225+ public function offsetSet ($ offset , $ value )
226+ {
227+ throw new Exception ("JSONDB Query Result Error: Trying to change a result value. The action isn't allowed. " );
228+ }
229+
230+ /**
231+ * Unsets a result at the given offset
232+ * @param int $offset
233+ * @return void
234+ */
235+ public function offsetUnset ($ offset )
236+ {
237+ if ($ this ->offsetExists ($ offset )) {
238+ unset($ this ->results [$ offset ]);
239+ $ this ->_setResults (array_values (array_slice ($ this ->results , 2 )));
240+ $ this ->_parseResults ();
241+ }
242+ }
243+
244+ /**
245+ * Fetch for results
246+ * @param int $mode The fetch mode
247+ * @return array|QueryResultObject|null
248+ * @throws Exception
249+ */
250+ public function fetch ($ mode = NULL )
251+ {
252+ if (NULL !== $ mode ) {
253+ $ this ->setFetchMode ($ mode );
254+ }
255+
256+ if ($ this ->database ->queryIsExecuted ()) {
257+ if ($ this ->valid ()) {
258+ $ return = $ this ->current ();
259+ ++$ this ->key ;
260+
261+ switch ($ this ->fetchMode ) {
262+ case JSONDB ::FETCH_ARRAY :
263+ return (array )$ return ;
264+
265+ case JSONDB ::FETCH_OBJECT :
266+ return new QueryResultObject ($ return );
267+ }
268+ }
269+ return NULL ;
270+ } else {
271+ throw new Exception ("JSONDB Query Result Error: Can't fetch for results without execute the query. " );
272+ }
273+ }
274+
275+ /**
276+ * Changes the fetch mode
277+ * @param int $mode
278+ */
279+ public function setFetchMode ($ mode = JSONDB ::FETCH_ARRAY )
280+ {
281+ $ this ->fetchMode = $ mode ;
282+ }
283+
284+ /**
285+ * Adds information in results
286+ */
287+ private function _parseResults ()
288+ {
289+ $ this ->results = array_merge (
290+ array ('#queryString ' => $ this ->database ->queryString (),
291+ '#elapsedtime ' => $ this ->database ->benchmark ()->elapsed_time ('jsondb_(query)_start ' , 'jsondb_(query)_end ' ))
292+ , $ this ->results );
293+ }
294+ }
295+
296+ /**
297+ * Class QueryResultObject
298+ *
299+ * @package JSONDB
300+ * @subpackage Utilities
301+ * @category Results
302+ * @author Nana Axel
303+ */
304+ class QueryResultObject
305+ {
306+ /**
307+ * The specified result
308+ * @var array
309+ */
310+ private $ result ;
311+
312+ /**
313+ * ObjectQueryResult __constructor.
314+ * @param array $result_array
315+ */
316+ public function __construct (array $ result_array )
317+ {
318+ $ this ->_setResult ($ result_array );
319+ }
320+
321+ /**
322+ * @param mixed $result
323+ */
324+ private function _setResult ($ result )
325+ {
326+ $ this ->result = $ result ;
327+ }
328+
329+ /**
330+ * @param string $name
331+ * @return mixed
332+ * @throws Exception
333+ */
334+ public function __get ($ name )
335+ {
336+ if (array_key_exists ($ name , $ this ->result )) {
337+ return $ this ->result [$ name ];
338+ } else {
339+ throw new Exception ("JSONDB Query Result Error: Can't access the key \"{$ name }\" in result, maybe the key doesn't exist. " );
340+ }
341+ }
342+ }
0 commit comments