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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Oct 29 19:11:41 2002 UTC (21 years, 8 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: Frank M. Kromann <frank@frontbase.com> |
17     // +----------------------------------------------------------------------+
18     //
19     // $Id: fbsql.php,v 1.14 2002/02/28 08:27:08 sebastian Exp $
20     //
21     // Database independent query interface definition for PHP's FrontBase
22     // extension.
23     //
24    
25     //
26     // XXX legend:
27     //
28     // XXX ERRORMSG: The error message from the fbsql function should
29     // be registered here.
30     //
31    
32     require_once "DB/common.php";
33    
34     class DB_fbsql extends DB_common
35     {
36     // {{{ properties
37    
38     var $connection;
39     var $phptype, $dbsyntax;
40     var $prepare_tokens = array();
41     var $prepare_types = array();
42     var $num_rows = array();
43     var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
44    
45     // }}}
46     // {{{ constructor
47    
48     /**
49     * DB_fbsql constructor.
50     *
51     * @access public
52     */
53    
54     function DB_fbsql()
55     {
56     $this->DB_common();
57     $this->phptype = 'fbsql';
58     $this->dbsyntax = 'fbsql';
59     $this->features = array(
60     'prepare' => false,
61     'pconnect' => true,
62     'transactions' => true,
63     'limit' => 'emulate'
64     );
65     $this->errorcode_map = array(
66     1004 => DB_ERROR_CANNOT_CREATE,
67     1005 => DB_ERROR_CANNOT_CREATE,
68     1006 => DB_ERROR_CANNOT_CREATE,
69     1007 => DB_ERROR_ALREADY_EXISTS,
70     1008 => DB_ERROR_CANNOT_DROP,
71     1046 => DB_ERROR_NODBSELECTED,
72     1050 => DB_ERROR_ALREADY_EXISTS,
73     1051 => DB_ERROR_NOSUCHTABLE,
74     1054 => DB_ERROR_NOSUCHFIELD,
75     1062 => DB_ERROR_ALREADY_EXISTS,
76     1064 => DB_ERROR_SYNTAX,
77     1100 => DB_ERROR_NOT_LOCKED,
78     1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
79     1146 => DB_ERROR_NOSUCHTABLE,
80     );
81     }
82    
83     // }}}
84    
85     // {{{ connect()
86    
87     /**
88     * Connect to a database and log in as the specified user.
89     *
90     * @param $dsn the data source name (see DB::parseDSN for syntax)
91     * @param $persistent (optional) whether the connection should
92     * be persistent
93     * @access public
94     * @return int DB_OK on success, a DB error on failure
95     */
96    
97     function connect($dsninfo, $persistent = false)
98     {
99     if (!DB::assertExtension('fbsql'))
100     return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
101    
102     $this->dsn = $dsninfo;
103     $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
104     $user = $dsninfo['username'];
105     $pw = $dsninfo['password'];
106    
107     $connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect';
108    
109     ini_set('track_errors', true);
110     if ($dbhost && $user && $pw) {
111     $conn = @$connect_function($dbhost, $user, $pw);
112     } elseif ($dbhost && $user) {
113     $conn = @$connect_function($dbhost, $user);
114     } elseif ($dbhost) {
115     $conn = @$connect_function($dbhost);
116     } else {
117     $conn = false;
118     }
119     ini_restore("track_errors");
120     if (empty($conn)) {
121     if (empty($php_errormsg)) {
122     return $this->raiseError(DB_ERROR_CONNECT_FAILED);
123     } else {
124     return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
125     null, $php_errormsg);
126     }
127     }
128    
129     if ($dsninfo['database']) {
130     if (!fbsql_select_db($dsninfo['database'], $conn)) {
131     return $this->fbsqlRaiseError();
132     }
133     }
134    
135     $this->connection = $conn;
136     return DB_OK;
137     }
138    
139     // }}}
140     // {{{ disconnect()
141    
142     /**
143     * Log out and disconnect from the database.
144     *
145     * @access public
146     *
147     * @return bool TRUE on success, FALSE if not connected.
148     */
149     function disconnect()
150     {
151     $ret = fbsql_close($this->connection);
152     $this->connection = null;
153     return $ret;
154     }
155    
156     // }}}
157     // {{{ simpleQuery()
158    
159     /**
160     * Send a query to fbsql and return the results as a fbsql resource
161     * identifier.
162     *
163     * @param the SQL query
164     *
165     * @access public
166     *
167     * @return mixed returns a valid fbsql result for successful SELECT
168     * queries, DB_OK for other successful queries. A DB error is
169     * returned on failure.
170     */
171     function simpleQuery($query)
172     {
173     $this->last_query = $query;
174     $query = $this->modifyQuery($query);
175     $result = @fbsql_query("$query;", $this->connection);
176     if (!$result) {
177     return $this->fbsqlRaiseError();
178     }
179     // Determine which queries that should return data, and which
180     // should return an error code only.
181     if (DB::isManip($query)) {
182     return DB_OK;
183     }
184     $numrows = $this->numrows($result);
185     if (is_object($numrows)) {
186     return $numrows;
187     }
188     $this->num_rows[$result] = $numrows;
189     return $result;
190     }
191    
192     // }}}
193     // {{{ nextResult()
194    
195     /**
196     * Move the internal fbsql result pointer to the next available result
197     *
198     * @param a valid fbsql result resource
199     *
200     * @access public
201     *
202     * @return true if a result is available otherwise return false
203     */
204     function nextResult($result)
205     {
206     return @fbsql_next_result($result);
207     }
208    
209     // }}}
210     // {{{ fetchRow()
211    
212     /**
213     * Fetch and return a row of data (it uses fetchInto for that)
214     * @param $result fbsql result identifier
215     * @param $fetchmode format of fetched row array
216     * @param $rownum the absolute row number to fetch
217     *
218     * @return array a row of data, or false on error
219     */
220     function fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
221     {
222     if ($fetchmode == DB_FETCHMODE_DEFAULT) {
223     $fetchmode = $this->fetchmode;
224     }
225     $res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
226     if ($res !== DB_OK) {
227     return $res;
228     }
229     return $arr;
230     }
231    
232     // }}}
233     // {{{ fetchInto()
234    
235     /**
236     * Fetch a row and insert the data into an existing array.
237     *
238     * @param $result fbsql result identifier
239     * @param $arr (reference) array where data from the row is stored
240     * @param $fetchmode how the array data should be indexed
241     * @param $rownum the row number to fetch
242     * @access public
243     *
244     * @return int DB_OK on success, a DB error on failure
245     */
246     function fetchInto($result, &$arr, $fetchmode, $rownum=null)
247     {
248     if ($rownum !== null) {
249     if (!@fbsql_data_seek($result, $rownum)) {
250     return null;
251     }
252     }
253     if ($fetchmode & DB_FETCHMODE_ASSOC) {
254     $arr = @fbsql_fetch_array($result, FBSQL_ASSOC);
255     } else {
256     $arr = @fbsql_fetch_row($result);
257     }
258     if (!$arr) {
259     $errno = @fbsql_errno($this->connection);
260     if (!$errno) {
261     return NULL;
262     }
263     return $this->fbsqlRaiseError($errno);
264     }
265     return DB_OK;
266     }
267    
268     // }}}
269     // {{{ freeResult()
270    
271     /**
272     * Free the internal resources associated with $result.
273     *
274     * @param $result fbsql result identifier or DB statement identifier
275     *
276     * @access public
277     *
278     * @return bool TRUE on success, FALSE if $result is invalid
279     */
280     function freeResult($result)
281     {
282     if (is_resource($result)) {
283     return fbsql_free_result($result);
284     }
285    
286     if (!isset($this->prepare_tokens[(int)$result])) {
287     return false;
288     }
289    
290     unset($this->prepare_tokens[(int)$result]);
291     unset($this->prepare_types[(int)$result]);
292    
293     return true;
294     }
295    
296     // }}}
297     // {{{ autoCommit()
298    
299     function autoCommit($onoff=false)
300     {
301     if ($onoff) {
302     $this->query("SET COMMIT TRUE");
303     } else {
304     $this->query("SET COMMIT FALSE");
305     }
306     }
307    
308     // }}}
309     // {{{ commit()
310    
311     function commit()
312     {
313     fbsql_commit();
314     }
315    
316     // }}}
317     // {{{ rollback()
318    
319     function rollback()
320     {
321     fbsql_rollback();
322     }
323    
324     // }}}
325     // {{{ numCols()
326    
327     /**
328     * Get the number of columns in a result set.
329     *
330     * @param $result fbsql result identifier
331     *
332     * @access public
333     *
334     * @return int the number of columns per row in $result
335     */
336     function numCols($result)
337     {
338     $cols = @fbsql_num_fields($result);
339    
340     if (!$cols) {
341     return $this->fbsqlRaiseError();
342     }
343    
344     return $cols;
345     }
346    
347     // }}}
348     // {{{ numRows()
349    
350     /**
351     * Get the number of rows in a result set.
352     *
353     * @param $result fbsql result identifier
354     *
355     * @access public
356     *
357     * @return int the number of rows in $result
358     */
359     function numRows($result)
360     {
361     $rows = @fbsql_num_rows($result);
362     if ($rows === null) {
363     return $this->fbsqlRaiseError();
364     }
365     return $rows;
366     }
367    
368     // }}}
369     // {{{ affectedRows()
370    
371     /**
372     * Gets the number of rows affected by the data manipulation
373     * query. For other queries, this function returns 0.
374     *
375     * @return number of rows affected by the last query
376     */
377    
378     function affectedRows()
379     {
380     if (DB::isManip($this->last_query)) {
381     $result = @fbsql_affected_rows($this->connection);
382     } else {
383     $result = 0;
384     }
385     return $result;
386     }
387    
388     // }}}
389     // {{{ errorNative()
390    
391     /**
392     * Get the native error code of the last error (if any) that
393     * occured on the current connection.
394     *
395     * @access public
396     *
397     * @return int native fbsql error code
398     */
399    
400     function errorNative()
401     {
402     return fbsql_errno($this->connection);
403     }
404    
405     // }}}
406     // {{{ nextId()
407    
408     /**
409     * Get the next value in a sequence. We emulate sequences
410     * for fbsql. Will create the sequence if it does not exist.
411     *
412     * @access public
413     *
414     * @param $seq_name the name of the sequence
415     *
416     * @param $ondemand whether to create the sequence table on demand
417     * (default is true)
418     *
419     * @return a sequence integer, or a DB error
420     */
421     function nextId($seq_name, $ondemand = true)
422     {
423     $sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
424     $repeat = 0;
425     do {
426     $seqname = sprintf($this->getOption("seqname_format"), $sqn);
427     $result = $this->query("INSERT INTO ${seqname} VALUES(NULL)");
428     if ($ondemand && DB::isError($result) &&
429     $result->getCode() == DB_ERROR_NOSUCHTABLE) {
430     $repeat = 1;
431     $result = $this->createSequence($seq_name);
432     if (DB::isError($result)) {
433     return $result;
434     }
435     } else {
436     $repeat = 0;
437     }
438     } while ($repeat);
439     if (DB::isError($result)) {
440     return $result;
441     }
442     return fbsql_insert_id($this->connection);
443     }
444    
445     // }}}
446     // {{{ createSequence()
447    
448     function createSequence($seq_name)
449     {
450     $sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
451     $seqname = sprintf($this->getOption("seqname_format"), $sqn);
452     return $this->query("CREATE TABLE ${seqname} ".
453     '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'.
454     ' PRIMARY KEY(id))');
455     }
456    
457     // }}}
458     // {{{ dropSequence()
459    
460     function dropSequence($seq_name)
461     {
462     $sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
463     $seqname = sprintf($this->getOption("seqname_format"), $sqn);
464     return $this->query("DROP TABLE ${seqname} RESTRICT");
465     }
466    
467     // }}}
468     // {{{ modifyQuery()
469    
470     function modifyQuery($query)
471     {
472     if ($this->options['optimize'] == 'portability') {
473     // "DELETE FROM table" gives 0 affected rows in fbsql.
474     // This little hack lets you know how many rows were deleted.
475     if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
476     $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
477     'DELETE FROM \1 WHERE 1=1', $query);
478     }
479     }
480     return $query;
481     }
482    
483     // }}}
484     // {{{ fbsqlRaiseError()
485    
486     function fbsqlRaiseError($errno = null)
487     {
488     if ($errno === null) {
489     $errno = $this->errorCode(fbsql_errno($this->connection));
490     }
491     return $this->raiseError($errno, null, null, null,
492     fbsql_error($this->connection));
493     }
494    
495     // }}}
496     // {{{ tableInfo()
497    
498     function tableInfo($result, $mode = null) {
499     $count = 0;
500     $id = 0;
501     $res = array();
502    
503     /*
504     * depending on $mode, metadata returns the following values:
505     *
506     * - mode is false (default):
507     * $result[]:
508     * [0]["table"] table name
509     * [0]["name"] field name
510     * [0]["type"] field type
511     * [0]["len"] field length
512     * [0]["flags"] field flags
513     *
514     * - mode is DB_TABLEINFO_ORDER
515     * $result[]:
516     * ["num_fields"] number of metadata records
517     * [0]["table"] table name
518     * [0]["name"] field name
519     * [0]["type"] field type
520     * [0]["len"] field length
521     * [0]["flags"] field flags
522     * ["order"][field name] index of field named "field name"
523     * The last one is used, if you have a field name, but no index.
524     * Test: if (isset($result['meta']['myfield'])) { ...
525     *
526     * - mode is DB_TABLEINFO_ORDERTABLE
527     * the same as above. but additionally
528     * ["ordertable"][table name][field name] index of field
529     * named "field name"
530     *
531     * this is, because if you have fields from different
532     * tables with the same field name * they override each
533     * other with DB_TABLEINFO_ORDER
534     *
535     * you can combine DB_TABLEINFO_ORDER and
536     * DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
537     * DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
538     */
539    
540     // if $result is a string, then we want information about a
541     // table without a resultset
542     if (is_string($result)) {
543     $id = @fbsql_list_fields($this->dsn['database'],
544     $result, $this->connection);
545     if (empty($id)) {
546     return $this->fbsqlRaiseError();
547     }
548     } else { // else we want information about a resultset
549     $id = $result;
550     if (empty($id)) {
551     return $this->fbsqlRaiseError();
552     }
553     }
554    
555     $count = @fbsql_num_fields($id);
556    
557     // made this IF due to performance (one if is faster than $count if's)
558     if (empty($mode)) {
559     for ($i=0; $i<$count; $i++) {
560     $res[$i]['table'] = @fbsql_field_table ($id, $i);
561     $res[$i]['name'] = @fbsql_field_name ($id, $i);
562     $res[$i]['type'] = @fbsql_field_type ($id, $i);
563     $res[$i]['len'] = @fbsql_field_len ($id, $i);
564     $res[$i]['flags'] = @fbsql_field_flags ($id, $i);
565     }
566     } else { // full
567     $res["num_fields"]= $count;
568    
569     for ($i=0; $i<$count; $i++) {
570     $res[$i]['table'] = @fbsql_field_table ($id, $i);
571     $res[$i]['name'] = @fbsql_field_name ($id, $i);
572     $res[$i]['type'] = @fbsql_field_type ($id, $i);
573     $res[$i]['len'] = @fbsql_field_len ($id, $i);
574     $res[$i]['flags'] = @fbsql_field_flags ($id, $i);
575     if ($mode & DB_TABLEINFO_ORDER) {
576     $res['order'][$res[$i]['name']] = $i;
577     }
578     if ($mode & DB_TABLEINFO_ORDERTABLE) {
579     $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
580     }
581     }
582     }
583    
584     // free the result only if we were called on a table
585     if (is_string($result)) {
586     @fbsql_free_result($id);
587     }
588     return $res;
589     }
590    
591     // }}}
592     // {{{ getSpecialQuery()
593    
594     /**
595     * Returns the query needed to get some backend info
596     * @param string $type What kind of info you want to retrieve
597     * @return string The SQL query string
598     */
599     function getSpecialQuery($type)
600     {
601     switch ($type) {
602     case 'tables':
603     $sql = 'select "table_name" from information_schema.tables';
604     break;
605     default:
606     return null;
607     }
608     return $sql;
609     }
610    
611     // }}}
612     }
613    
614     // TODO/wishlist:
615     // longReadlen
616     // binmode
617    
618     ?>

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