1<?php
2/**
3 * EGroupware API: Database api deprecated functionality
4 *
5 * @link http://www.egroupware.org
6 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
7 * @package api
8 * @subpackage db
9 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
10 * @copyright (c) 2003-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
11 * @version $Id$
12 */
13
14namespace EGroupware\Api\Db;
15
16use EGroupware\Api;
17
18/**
19 * Deprecated functionality we still need to support :-(
20 *
21 * This functions store result of last query in class variable Query_ID,
22 * instead of operating on iterator / record-set returned by query method.
23 *
24 * You only need to clone the global database object $GLOBALS['egw']->db if:
25 * - you use the old methods f(), next_record(), row(), num_fields(), num_rows()
26 * - you access an application table (non phpgwapi) and you want to call set_app()
27 *
28 * Otherwise you can simply use $GLOBALS['egw']->db or a reference to it.
29 *
30 * Avoiding next_record() or row() can be done by looping with the recordset returned by query() or select():
31 *
32 * @deprecated use just EGroupware\Api\Db
33 */
34class Deprecated extends Api\Db
35{
36	/**
37	 * ADOdb record set of the current query
38	 *
39	 * @var ADORecordSet
40	 */
41	var $Query_ID = 0;
42
43	/**
44	* Execute a query
45	*
46	* @param string $Query_String the query to be executed
47	* @param int $line the line method was called from - use __LINE__
48	* @param string $file the file method was called from - use __FILE__
49	* @param int $offset row to start from, default 0
50	* @param int $num_rows number of rows to return (optional), default -1 = all, 0 will use $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs']
51	* @param array|boolean $inputarr array for binding variables to parameters or false (default)
52	* @param int $fetchmode =self::FETCH_BOTH self::FETCH_BOTH (default), self::FETCH_ASSOC or self::FETCH_NUM
53	* @param boolean $reconnect =true true: try reconnecting if server closes connection, false: dont (mysql only!)
54	* @return ADORecordSet or false, if the query fails
55	* @throws EGroupware\Api\Db\Exception\InvalidSql with $this->Link_ID->ErrorNo() as code
56	*/
57	function query($Query_String, $line = '', $file = '', $offset=0, $num_rows=-1, $inputarr=false, $fetchmode=self::FETCH_BOTH, $reconnect=true)
58	{
59		// New query, discard previous result.
60		if ($this->Query_ID)
61		{
62			$this->free();
63		}
64		return $this->Query_ID = parent::query($Query_String, $line, $file, $offset, $num_rows, $inputarr, $fetchmode, $reconnect);
65	}
66
67	/**
68	 * Return the result-object of the last query
69	 *
70	 * @deprecated use the result-object returned by query() or select() direct, so you can use the global db-object and not a clone
71	 * @return ADORecordSet
72	 */
73	function query_id()
74	{
75		return $this->Query_ID;
76	}
77
78	/**
79	* Escape strings before sending them to the database
80	*
81	* @deprecated use quote($value,$type='') instead
82	* @param string $str the string to be escaped
83	* @return string escaped sting
84	*/
85	function db_addslashes($str)
86	{
87		if (!isset($str) || $str == '')
88		{
89			return '';
90		}
91		if (!$this->Link_ID && !$this->connect())
92		{
93			return False;
94		}
95		return $this->Link_ID->addq($str);
96	}
97
98	/**
99	 * Discard the current query result
100	 *
101	 * @deprecated use the result-object returned by query() or select() direct, so you can use the global db-object and not a clone
102	 */
103	function free()
104	{
105		unset($this->Query_ID);	// else copying of the db-object does not work
106		$this->Query_ID = 0;
107	}
108
109	/**
110	* Move to the next row in the results set
111	*
112	* Specifying a fetch_mode only works for newly fetched rows, the first row always gets fetched by query!!!
113	*
114	* @deprecated use foreach(query() or foreach(select() to loop over the query using the global db object
115	* @param int $fetch_mode self::FETCH_BOTH = numerical+assoc keys (eGW default), self::FETCH_ASSOC or self::FETCH_NUM
116	* @return bool was another row found?
117	*/
118	function next_record($fetch_mode=self::FETCH_BOTH)
119	{
120		if (!$this->Query_ID)
121		{
122			throw new Exception('next_record called with no query pending.');
123		}
124		if ($this->Row)	// first row is already fetched
125		{
126			$this->Query_ID->MoveNext();
127		}
128		++$this->Row;
129
130		$this->Record = $this->Query_ID->fields;
131
132		if ($this->Query_ID->EOF || !$this->Query_ID->RecordCount() || !is_array($this->Record))
133		{
134			return False;
135		}
136		if ($this->capabilities[self::CAPABILITY_NAME_CASE] == 'upper')	// maxdb, oracle, ...
137		{
138			switch($fetch_mode)
139			{
140				case self::FETCH_ASSOC:
141					$this->Record = array_change_key_case($this->Record);
142					break;
143				case self::FETCH_NUM:
144					$this->Record = array_values($this->Record);
145					break;
146				default:
147					$this->Record = array_change_key_case($this->Record);
148					if (!isset($this->Record[0]))
149					{
150						$this->Record += array_values($this->Record);
151					}
152					break;
153			}
154		}
155		// fix the result if it was fetched ASSOC and now NUM OR BOTH is required, as default for select() is now ASSOC
156		elseif ($this->Link_ID->fetchMode != $fetch_mode)
157		{
158			if (!isset($this->Record[0]))
159			{
160				$this->Record += array_values($this->Record);
161			}
162		}
163		return True;
164	}
165
166	/**
167	* Move to position in result set
168	*
169	* @deprecated use the result-object returned by query() or select() direct, so you can use the global db-object and not a clone
170	* @param int $pos required row (optional), default first row
171	* @return boolean true if sucessful or false if not found
172	*/
173	function seek($pos = 0)
174	{
175		if (!$this->Query_ID  || !$this->Query_ID->Move($this->Row = $pos))
176		{
177			throw new Exception("seek($pos) failed: resultset has " . $this->num_rows() . " rows");
178		}
179		return True;
180	}
181
182	/**
183	* Lock a table
184	*
185	* @deprecated not used anymore as it costs to much performance, use transactions if needed
186	* @param string $table name of table to lock
187	* @param string $mode type of lock required (optional), default write
188	* @return bool True if sucessful, False if fails
189	*/
190	function lock($table, $mode='write')
191	{
192		unset($table, $mode);	// not used anymore
193	}
194
195	/**
196	* Unlock a table
197	*
198	* @deprecated not used anymore as it costs to much performance, use transactions if needed
199	* @return bool True if sucessful, False if fails
200	*/
201	function unlock()
202	{}
203
204	/**
205	* Number of rows in current result set
206	*
207	* @deprecated use the result-object returned by query/select()->NumRows(), so you can use the global db-object and not a clone
208	* @return int number of rows
209	*/
210	function num_rows()
211	{
212		return $this->Query_ID ? $this->Query_ID->RecordCount() : False;
213	}
214
215	/**
216	* Number of fields in current row
217	*
218	* @deprecated use the result-object returned by query() or select() direct, so you can use the global db-object and not a clone
219	* @return int number of fields
220	*/
221	function num_fields()
222	{
223		return $this->Query_ID ? $this->Query_ID->FieldCount() : False;
224	}
225
226	/**
227	* @deprecated use num_rows()
228	*/
229	function nf()
230	{
231		return $this->num_rows();
232	}
233
234	/**
235	* @deprecated use print num_rows()
236	*/
237	function np()
238	{
239		print $this->num_rows();
240	}
241
242	/**
243	* Return the value of a column
244	*
245	* @deprecated use the result-object returned by query() or select() direct, so you can use the global db-object and not a clone
246	* @param string|integer $Name name of field or positional index starting from 0
247	* @param bool $strip_slashes string escape chars from field(optional), default false
248	*	depricated param, as correctly quoted values dont need any stripslashes!
249	* @return string the field value
250	*/
251	function f($Name, $strip_slashes = False)
252	{
253		if ($strip_slashes)
254		{
255			return stripslashes($this->Record[$Name]);
256		}
257		return $this->Record[$Name];
258	}
259
260	/**
261	* Print the value of a field
262	*
263	* @deprecated use the result-object returned by query() or select() direct, so you can use the global db-object and not a clone
264	* @param string $Name name of field to print
265	* @param bool $strip_slashes string escape chars from field(optional), default false
266	*	depricated param, as correctly quoted values dont need any stripslashes!
267	*/
268	function p($Name, $strip_slashes = True)
269	{
270		print $this->f($Name, $strip_slashes);
271	}
272
273	/**
274	* Returns a query-result-row as an associative array (no numerical keys !!!)
275	*
276	* @deprecated use foreach(query() or foreach(select() to loop over the query using the global db object
277	* @param bool $do_next_record should next_record() be called or not (default not)
278	* @param string $strip ='' string to strip of the column-name, default ''
279	* @return array/bool the associative array or False if no (more) result-row is availible
280	*/
281	function row($do_next_record=False,$strip='')
282	{
283		if ($do_next_record && !$this->next_record(self::FETCH_ASSOC) || !is_array($this->Record))
284		{
285			return False;
286		}
287		$result = array();
288		foreach($this->Record as $column => $value)
289		{
290			if (!is_numeric($column))
291			{
292				if ($strip) $column = str_replace($strip,'',$column);
293
294				$result[$column] = $value;
295			}
296		}
297		return $result;
298	}
299}
300
301/**
302 * @deprecated use EGroupware\Api\Db\CallbackIterator
303 */
304class egw_db_callback_iterator extends Api\Db\CallbackIterator {}
305