/[cvs]/nfo/php/libs/net.php.pear/DB/odbc.php
ViewVC logotype

Annotation of /nfo/php/libs/net.php.pear/DB/odbc.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Oct 29 19:11:41 2002 UTC (21 years, 9 months ago) by cvsjoko
Branch: MAIN
CVS Tags: HEAD
+ new pear-libraries

1 cvsjoko 1.1 <?php
2     //
3     // +----------------------------------------------------------------------+
4     // | PHP Version 4 |
5     // +----------------------------------------------------------------------+
6     // | Copyright (c) 1997-2002 The PHP Group |
7     // +----------------------------------------------------------------------+
8     // | This source file is subject to version 2.02 of the PHP license, |
9     // | that is bundled with this package in the file LICENSE, and is |
10     // | available at through the world-wide-web at |
11     // | http://www.php.net/license/2_02.txt. |
12     // | If you did not receive a copy of the PHP license and are unable to |
13     // | obtain it through the world-wide-web, please send a note to |
14     // | license@php.net so we can mail you a copy immediately. |
15     // +----------------------------------------------------------------------+
16     // | Author: Stig Bakken <ssb@fast.no> |
17     // +----------------------------------------------------------------------+
18     //
19     // $Id: odbc.php,v 1.54 2002/02/28 08:27:11 sebastian Exp $
20     //
21     // Database independent query interface definition for PHP's ODBC
22     // extension.
23     //
24    
25     //
26     // XXX legend:
27     // More info on ODBC errors could be found here:
28     // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp
29     //
30     // XXX ERRORMSG: The error message from the odbc function should
31     // be registered here.
32     //
33    
34     require_once 'DB/common.php';
35    
36     class DB_odbc extends DB_common
37     {
38     // {{{ properties
39    
40     var $connection;
41     var $phptype, $dbsyntax;
42     var $row = array();
43    
44     // }}}
45     // {{{ constructor
46    
47     function DB_odbc()
48     {
49     $this->DB_common();
50     $this->phptype = 'odbc';
51     $this->dbsyntax = 'sql92';
52     $this->features = array(
53     'prepare' => true,
54     'pconnect' => true,
55     'transactions' => false,
56     'limit' => 'emulate'
57     );
58     $this->errorcode_map = array(
59     '01004' => DB_ERROR_TRUNCATED,
60     '07001' => DB_ERROR_MISMATCH,
61     '21S01' => DB_ERROR_MISMATCH,
62     '21S02' => DB_ERROR_MISMATCH,
63     '22003' => DB_ERROR_INVALID_NUMBER,
64     '22008' => DB_ERROR_INVALID_DATE,
65     '22012' => DB_ERROR_DIVZERO,
66     '23000' => DB_ERROR_CONSTRAINT,
67     '24000' => DB_ERROR_INVALID,
68     '34000' => DB_ERROR_INVALID,
69     '37000' => DB_ERROR_SYNTAX,
70     '42000' => DB_ERROR_SYNTAX,
71     'IM001' => DB_ERROR_UNSUPPORTED,
72     'S0000' => DB_ERROR_NOSUCHTABLE,
73     'S0001' => DB_ERROR_NOT_FOUND,
74     'S0002' => DB_ERROR_NOT_FOUND,
75     'S0011' => DB_ERROR_ALREADY_EXISTS,
76     'S0012' => DB_ERROR_NOT_FOUND,
77     'S0021' => DB_ERROR_ALREADY_EXISTS,
78     'S0022' => DB_ERROR_NOT_FOUND,
79     'S1009' => DB_ERROR_INVALID,
80     'S1090' => DB_ERROR_INVALID,
81     'S1C00' => DB_ERROR_NOT_CAPABLE
82     );
83     }
84    
85     // }}}
86     // {{{ connect()
87    
88     /**
89     * Connect to a database and log in as the specified user.
90     *
91     * @param $dsn the data source name (see DB::parseDSN for syntax)
92     * @param $persistent (optional) whether the connection should
93     * be persistent
94     *
95     * @return int DB_OK on success, a DB error code on failure
96     */
97     function connect($dsninfo, $persistent = false)
98     {
99     if (!DB::assertExtension('odbc'))
100     return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
101    
102     $this->dsn = $dsninfo;
103     if (!empty($dsninfo['dbsyntax'])) {
104     $this->dbsyntax = $dsninfo['dbsyntax'];
105     }
106     switch ($this->dbsyntax) {
107     case 'solid':
108     $this->features = array(
109     'prepare' => true,
110     'pconnect' => true,
111     'transactions' => true
112     );
113     $default_dsn = 'localhost';
114     break;
115     case 'navision':
116     // the Navision driver doesn't support fetch row by number
117     $this->features['limit'] = false;
118     break;
119     default:
120     break;
121     }
122     $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
123     $user = $dsninfo['username'];
124     $pw = $dsninfo['password'];
125     if ($this->provides('pconnect')) {
126     $connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
127     } else {
128     $connect_function = 'odbc_connect';
129     }
130     $conn = @$connect_function($dbhost, $user, $pw);
131     if (!is_resource($conn)) {
132     return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
133     null, $this->errorNative());
134     }
135     $this->connection = $conn;
136     return DB_OK;
137     }
138    
139     // }}}
140     // {{{ disconnect()
141    
142     function disconnect()
143     {
144     $err = @odbc_close($this->connection);
145     $this->connection = null;
146     return $err;
147     }
148    
149     // }}}
150     // {{{ simpleQuery()
151    
152     /**
153     * Send a query to ODBC and return the results as a ODBC resource
154     * identifier.
155     *
156     * @param $query the SQL query
157     *
158     * @return int returns a valid ODBC result for successful SELECT
159     * queries, DB_OK for other successful queries. A DB error code
160     * is returned on failure.
161     */
162     function simpleQuery($query)
163     {
164     $this->last_query = $query;
165     $query = $this->modifyQuery($query);
166     $result = @odbc_exec($this->connection, $query);
167     if (!$result) {
168     return $this->odbcRaiseError(); // XXX ERRORMSG
169     }
170     // Determine which queries that should return data, and which
171     // should return an error code only.
172     if (DB::isManip($query)) {
173     $this->manip_result = $result; // For affectedRows()
174     return DB_OK;
175     }
176     $this->row[$result] = 0;
177     $this->manip_result = 0;
178     return $result;
179     }
180    
181     // }}}
182     // {{{ nextResult()
183    
184     /**
185     * Move the internal odbc result pointer to the next available result
186     *
187     * @param a valid fbsql result resource
188     *
189     * @access public
190     *
191     * @return true if a result is available otherwise return false
192     */
193     function nextResult($result)
194     {
195     return odbc_next_result($result);
196     }
197    
198     // }}}
199     // {{{ fetchRow()
200    
201     function fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
202     {
203     if ($fetchmode == DB_FETCHMODE_DEFAULT) {
204     $fetchmode = $this->fetchmode;
205     }
206     $res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
207     if ($res !== DB_OK) {
208     return $res;
209     }
210     return $arr;
211     }
212    
213     // }}}
214     // {{{ fetchInto()
215    
216     function fetchInto($result, &$row, $fetchmode, $rownum=null)
217     {
218     $row = array();
219     if ($rownum !== null) {
220     $rownum++; // ODBC first row is 1
221     if (!function_exists('version_compare') || version_compare(phpversion(), "4.0.5", "lt")) {
222     $cols = odbc_fetch_into($result, $rownum, &$row);
223     } else {
224     $cols = odbc_fetch_into($result, $rownum, $row);
225     }
226     } else {
227     if (!function_exists('version_compare') || version_compare(phpversion(), "4.0.5", "lt")) {
228     $cols = odbc_fetch_into($result, &$row);
229     } else {
230     $cols = odbc_fetch_into($result, $row);
231     }
232     }
233    
234     if (!$cols) {
235     /* XXX FIXME: doesn't work with unixODBC and easysoft
236     (get corrupted $errno values)
237     if ($errno = odbc_error($this->connection)) {
238     return $this->RaiseError($errno);
239     }*/
240     return null;
241     }
242     if ($fetchmode !== DB_FETCHMODE_ORDERED) {
243     for ($i = 0; $i < count($row); $i++) {
244     $colName = odbc_field_name($result, $i+1);
245     $a[$colName] = $row[$i];
246     }
247     $row = $a;
248     }
249     return DB_OK;
250     }
251    
252     // }}}
253     // {{{ freeResult()
254    
255     function freeResult($result)
256     {
257     if (is_resource($result)) {
258     // Always return true
259     return odbc_free_result($result);
260     }
261     if (!isset($this->prepare_tokens[(int)$result])) {
262     return false;
263     }
264     unset($this->prepare_tokens[(int)$result]);
265     unset($this->prepare_types[(int)$result]);
266     return true;
267     }
268    
269     // }}}
270     // {{{ numCols()
271    
272     function numCols($result)
273     {
274     $cols = @odbc_num_fields($result);
275     if (!$cols) {
276     return $this->odbcRaiseError();
277     }
278     return $cols;
279     }
280    
281     // }}}
282     // {{{ affectedRows()
283    
284     /**
285     * Returns the number of rows affected by a manipulative query
286     * (INSERT, DELETE, UPDATE)
287     * @return mixed int affected rows, 0 when non manip queries or
288     * DB error on error
289     */
290     function affectedRows()
291     {
292     if (empty($this->manip_result)) { // In case of SELECT stms
293     return 0;
294     }
295     $nrows = odbc_num_rows($this->manip_result);
296     if ($nrows == -1) {
297     return $this->odbcRaiseError();
298     }
299     return $nrows;
300     }
301    
302     // }}}
303     // {{{ numRows()
304    
305     /**
306     * ODBC may or may not support counting rows in the result set of
307     * SELECTs.
308     *
309     * @param $result the odbc result resource
310     * @return the number of rows, or 0
311     */
312     function numRows($result)
313     {
314     $nrows = odbc_num_rows($result);
315     if ($nrows == -1) {
316     return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
317     }
318     return $nrows;
319     }
320    
321     // }}}
322     // {{{ errorNative()
323    
324     /**
325     * Get the native error code of the last error (if any) that
326     * occured on the current connection.
327     *
328     * @access public
329     *
330     * @return int ODBC error code
331     */
332    
333     function errorNative()
334     {
335     if (!isset($this->connection) || !is_resource($this->connection)) {
336     return odbc_error() . ' ' . odbc_errormsg();
337     }
338     return odbc_error($this->connection) . ' ' . odbc_errormsg($this->connection);
339     }
340    
341     // }}}
342     // {{{ nextId()
343    
344     /**
345     * Get the next value in a sequence. We emulate sequences
346     * for odbc. Will create the sequence if it does not exist.
347     *
348     * @access public
349     *
350     * @param $seq_name the name of the sequence
351     *
352     * @param $ondemand whether to create the sequence table on demand
353     * (default is true)
354     *
355     * @return a sequence integer, or a DB error
356     */
357     function nextId($seq_name, $ondemand = true)
358     {
359     $seqname = $this->getSequenceName($seq_name);
360     $repeat = 0;
361     do {
362     $result = $this->query("update ${seqname} set id = id + 1");
363     if ($ondemand && DB::isError($result) &&
364     $result->getCode() == DB_ERROR_NOT_FOUND) {
365     $repeat = 1;
366     $result = $this->createSequence($seq_name);
367     if (DB::isError($result)) {
368     return $result;
369     }
370     $result = $this->query("insert into ${seqname} (id) values(0)");
371     } else {
372     $repeat = 0;
373     }
374     } while ($repeat);
375    
376     if (DB::isError($result)) {
377     return $result;
378     }
379    
380     $result = $this->query("select id from ${seqname}");
381     if (DB::isError($result)) {
382     return $result;
383     }
384    
385     $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
386     if (DB::isError($row || !$row)) {
387     return $row;
388     }
389    
390     return $row['id'];
391     }
392    
393     // }}}
394     // {{{ createSequence()
395    
396     function createSequence($seq_name)
397     {
398     $seqname = $this->getSequenceName($seq_name);
399     return $this->query("CREATE TABLE ${seqname} ".
400     '(id bigint NOT NULL,'.
401     ' PRIMARY KEY(id))');
402     }
403    
404     // }}}
405     // {{{ dropSequence()
406    
407     function dropSequence($seq_name)
408     {
409     $seqname = $this->getSequenceName($seq_name);
410     return $this->query("DROP TABLE ${seqname}");
411     }
412    
413     // }}}
414     // {{{ autoCommit()
415    
416     function autoCommit($onoff = false)
417     {
418     if (!@odbc_autocommit($this->connection, $onoff)) {
419     return $this->odbcRaiseError();
420     }
421     return DB_OK;
422     }
423    
424     // }}}
425     // {{{ commit()
426    
427     function commit()
428     {
429     if (!@odbc_commit($this->connection)) {
430     return $this->odbcRaiseError();
431     }
432     return DB_OK;
433     }
434    
435     // }}}
436     // {{{ rollback()
437    
438     function rollback()
439     {
440     if (!@odbc_rollback($this->connection)) {
441     return $this->odbcRaiseError();
442     }
443     return DB_OK;
444     }
445    
446     // }}}
447     // {{{ odbcRaiseError()
448    
449     function odbcRaiseError($errno = null)
450     {
451     if ($errno === null) {
452     $errno = $this->errorCode(odbc_error($this->connection));
453     }
454     return $this->raiseError($errno, null, null, null,
455     $this->errorNative());
456     }
457    
458     // }}}
459     // {{{ getSpecialQuery()
460    
461     /**
462     * Returns the query needed to get some backend info
463     * @param string $type What kind of info you want to retrieve
464     * @return string The SQL query string
465     */
466     function getSpecialQuery($type)
467     {
468     switch ($type) {
469     case 'tables':
470     default:
471     return null;
472     }
473     return $sql;
474     }
475    
476     // }}}
477    
478     }
479    
480     // Local variables:
481     // tab-width: 4
482     // c-basic-offset: 4
483     // End:
484     ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed