~ubuntu-branches/ubuntu/hardy/gallery2/hardy-security

« back to all changes in this revision

Viewing changes to lib/adodb/drivers/adodb-odbc.inc.php

  • Committer: Bazaar Package Importer
  • Author(s): Michael C. Schultheiss
  • Date: 2006-04-16 16:42:35 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060416164235-8uy0u4bfjdxpge2o
Tags: 2.1.1-1
* New upstream release (Closes: #362936)
  + Bugfixes for Postgres7 (Closes: #359000, #362152)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/* 
 
3
V4.65 22 July 2005  (c) 2000-2005 John Lim (jlim#natsoft.com.my). All rights reserved.
 
4
  Released under both BSD license and Lesser GPL library license. 
 
5
  Whenever there is any discrepancy between the two licenses, 
 
6
  the BSD license will take precedence. 
 
7
Set tabs to 4 for best viewing.
 
8
  
 
9
  Latest version is available at http://adodb.sourceforge.net
 
10
  
 
11
  Requires ODBC. Works on Windows and Unix.
 
12
*/
 
13
// security - hide paths
 
14
if (!defined('ADODB_DIR')) die();
 
15
 
 
16
  define("_ADODB_ODBC_LAYER", 2 );
 
17
         
 
18
/*--------------------------------------------------------------------------------------
 
19
--------------------------------------------------------------------------------------*/
 
20
 
 
21
 
 
22
class ADODB_odbc extends ADOConnection {
 
23
        var $databaseType = "odbc";     
 
24
        var $fmtDate = "'Y-m-d'";
 
25
        var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
 
26
        var $replaceQuote = "''"; // string to use to replace quotes
 
27
        var $dataProvider = "odbc";
 
28
        var $hasAffectedRows = true;
 
29
        var $binmode = ODBC_BINMODE_RETURN;
 
30
        var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
 
31
                                                                // breaking backward-compat
 
32
        //var $longreadlen = 8000; // default number of chars to return for a Blob/Long field
 
33
        var $_bindInputArray = false;   
 
34
        var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
 
35
        var $_genSeqSQL = "create table %s (id integer)";
 
36
        var $_autocommit = true;
 
37
        var $_haserrorfunctions = true;
 
38
        var $_has_stupid_odbc_fetch_api_change = true;
 
39
        var $_lastAffectedRows = 0;
 
40
        var $uCaseTables = true; // for meta* functions, uppercase table names
 
41
        
 
42
        function ADODB_odbc() 
 
43
        {       
 
44
                $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
 
45
                $this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
 
46
        }
 
47
        
 
48
                // returns true or false
 
49
        function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
 
50
        {
 
51
        global $php_errormsg;
 
52
                
 
53
                if (!function_exists('odbc_connect')) return null;
 
54
                
 
55
                if ($this->debug && $argDatabasename && $this->databaseType != 'vfp') {
 
56
                        ADOConnection::outp("For odbc Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
 
57
                }
 
58
                if (isset($php_errormsg)) $php_errormsg = '';
 
59
                if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword);
 
60
                else $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,$this->curmode);
 
61
                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
 
62
                if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
 
63
                
 
64
                return $this->_connectionID != false;
 
65
        }
 
66
        
 
67
        // returns true or false
 
68
        function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
 
69
        {
 
70
        global $php_errormsg;
 
71
        
 
72
                if (!function_exists('odbc_connect')) return null;
 
73
                
 
74
                if (isset($php_errormsg)) $php_errormsg = '';
 
75
                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
 
76
                if ($this->debug && $argDatabasename) {
 
77
                        ADOConnection::outp("For odbc PConnect(), $argDatabasename is not used. Place dsn in 1st parameter.");
 
78
                }
 
79
        //      print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush();
 
80
                if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword);
 
81
                else $this->_connectionID = odbc_pconnect($argDSN,$argUsername,$argPassword,$this->curmode);
 
82
                
 
83
                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
 
84
                if ($this->_connectionID && $this->autoRollback) @odbc_rollback($this->_connectionID);
 
85
                if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
 
86
                
 
87
                return $this->_connectionID != false;
 
88
        }
 
89
 
 
90
        
 
91
        function ServerInfo()
 
92
        {
 
93
        
 
94
                if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
 
95
                        $dsn = strtoupper($this->host);
 
96
                        $first = true;
 
97
                        $found = false;
 
98
                        
 
99
                        if (!function_exists('odbc_data_source')) return false;
 
100
                        
 
101
                        while(true) {
 
102
                                
 
103
                                $rez = @odbc_data_source($this->_connectionID,
 
104
                                        $first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
 
105
                                $first = false;
 
106
                                if (!is_array($rez)) break;
 
107
                                if (strtoupper($rez['server']) == $dsn) {
 
108
                                        $found = true;
 
109
                                        break;
 
110
                                }
 
111
                        } 
 
112
                        if (!$found) return ADOConnection::ServerInfo();
 
113
                        if (!isset($rez['version'])) $rez['version'] = '';
 
114
                        return $rez;
 
115
                } else {
 
116
                        return ADOConnection::ServerInfo();
 
117
                }
 
118
        }
 
119
 
 
120
        
 
121
        function CreateSequence($seqname='adodbseq',$start=1)
 
122
        {
 
123
                if (empty($this->_genSeqSQL)) return false;
 
124
                $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
 
125
                if (!$ok) return false;
 
126
                $start -= 1;
 
127
                return $this->Execute("insert into $seqname values($start)");
 
128
        }
 
129
        
 
130
        var $_dropSeqSQL = 'drop table %s';
 
131
        function DropSequence($seqname)
 
132
        {
 
133
                if (empty($this->_dropSeqSQL)) return false;
 
134
                return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
 
135
        }
 
136
        
 
137
        /*
 
138
                This algorithm is not very efficient, but works even if table locking
 
139
                is not available.
 
140
                
 
141
                Will return false if unable to generate an ID after $MAXLOOPS attempts.
 
142
        */
 
143
        function GenID($seq='adodbseq',$start=1)
 
144
        {       
 
145
                // if you have to modify the parameter below, your database is overloaded,
 
146
                // or you need to implement generation of id's yourself!
 
147
                $MAXLOOPS = 100;
 
148
                //$this->debug=1;
 
149
                while (--$MAXLOOPS>=0) {
 
150
                        $num = $this->GetOne("select id from $seq");
 
151
                        if ($num === false) {
 
152
                                $this->Execute(sprintf($this->_genSeqSQL ,$seq));       
 
153
                                $start -= 1;
 
154
                                $num = '0';
 
155
                                $ok = $this->Execute("insert into $seq values($start)");
 
156
                                if (!$ok) return false;
 
157
                        } 
 
158
                        $this->Execute("update $seq set id=id+1 where id=$num");
 
159
                        
 
160
                        if ($this->affected_rows() > 0) {
 
161
                                $num += 1;
 
162
                                $this->genID = $num;
 
163
                                return $num;
 
164
                        }
 
165
                }
 
166
                if ($fn = $this->raiseErrorFn) {
 
167
                        $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
 
168
                }
 
169
                return false;
 
170
        }
 
171
 
 
172
 
 
173
        function ErrorMsg()
 
174
        {
 
175
                if ($this->_haserrorfunctions) {
 
176
                        if ($this->_errorMsg !== false) return $this->_errorMsg;
 
177
                        if (empty($this->_connectionID)) return @odbc_errormsg();
 
178
                        return @odbc_errormsg($this->_connectionID);
 
179
                } else return ADOConnection::ErrorMsg();
 
180
        }
 
181
        
 
182
        function ErrorNo()
 
183
        {
 
184
                
 
185
                if ($this->_haserrorfunctions) {
 
186
                        if ($this->_errorCode !== false) {
 
187
                                // bug in 4.0.6, error number can be corrupted string (should be 6 digits)
 
188
                                return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
 
189
                        }
 
190
 
 
191
                        if (empty($this->_connectionID)) $e = @odbc_error(); 
 
192
                        else $e = @odbc_error($this->_connectionID);
 
193
                        
 
194
                         // bug in 4.0.6, error number can be corrupted string (should be 6 digits)
 
195
                         // so we check and patch
 
196
                        if (strlen($e)<=2) return 0;
 
197
                        return $e;
 
198
                } else return ADOConnection::ErrorNo();
 
199
        }
 
200
        
 
201
        
 
202
 
 
203
        function BeginTrans()
 
204
        {       
 
205
                if (!$this->hasTransactions) return false;
 
206
                if ($this->transOff) return true; 
 
207
                $this->transCnt += 1;
 
208
                $this->_autocommit = false;
 
209
                return odbc_autocommit($this->_connectionID,false);
 
210
        }
 
211
        
 
212
        function CommitTrans($ok=true) 
 
213
        { 
 
214
                if ($this->transOff) return true; 
 
215
                if (!$ok) return $this->RollbackTrans();
 
216
                if ($this->transCnt) $this->transCnt -= 1;
 
217
                $this->_autocommit = true;
 
218
                $ret = odbc_commit($this->_connectionID);
 
219
                odbc_autocommit($this->_connectionID,true);
 
220
                return $ret;
 
221
        }
 
222
        
 
223
        function RollbackTrans()
 
224
        {
 
225
                if ($this->transOff) return true; 
 
226
                if ($this->transCnt) $this->transCnt -= 1;
 
227
                $this->_autocommit = true;
 
228
                $ret = odbc_rollback($this->_connectionID);
 
229
                odbc_autocommit($this->_connectionID,true);
 
230
                return $ret;
 
231
        }
 
232
        
 
233
        function MetaPrimaryKeys($table)
 
234
        {
 
235
        global $ADODB_FETCH_MODE;
 
236
        
 
237
                if ($this->uCaseTables) $table = strtoupper($table);
 
238
                $schema = '';
 
239
                $this->_findschema($table,$schema);
 
240
 
 
241
                $savem = $ADODB_FETCH_MODE;
 
242
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 
243
                $qid = @odbc_primarykeys($this->_connectionID,'',$schema,$table);
 
244
                
 
245
                if (!$qid) {
 
246
                        $ADODB_FETCH_MODE = $savem;
 
247
                        return false;
 
248
                }
 
249
                $rs = new ADORecordSet_odbc($qid);
 
250
                $ADODB_FETCH_MODE = $savem;
 
251
                
 
252
                if (!$rs) return false;
 
253
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
 
254
                
 
255
                $arr =& $rs->GetArray();
 
256
                $rs->Close();
 
257
                //print_r($arr);
 
258
                $arr2 = array();
 
259
                for ($i=0; $i < sizeof($arr); $i++) {
 
260
                        if ($arr[$i][3]) $arr2[] = $arr[$i][3];
 
261
                }
 
262
                return $arr2;
 
263
        }
 
264
        
 
265
        
 
266
        
 
267
        function &MetaTables($ttype=false)
 
268
        {
 
269
        global $ADODB_FETCH_MODE;
 
270
        
 
271
                $savem = $ADODB_FETCH_MODE;
 
272
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 
273
                $qid = odbc_tables($this->_connectionID);
 
274
                
 
275
                $rs = new ADORecordSet_odbc($qid);
 
276
                
 
277
                $ADODB_FETCH_MODE = $savem;
 
278
                if (!$rs) {
 
279
                        $false = false;
 
280
                        return $false;
 
281
                }
 
282
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
 
283
                
 
284
                $arr =& $rs->GetArray();
 
285
                //print_r($arr);
 
286
                
 
287
                $rs->Close();
 
288
                $arr2 = array();
 
289
                
 
290
                if ($ttype) {
 
291
                        $isview = strncmp($ttype,'V',1) === 0;
 
292
                }
 
293
                for ($i=0; $i < sizeof($arr); $i++) {
 
294
                        if (!$arr[$i][2]) continue;
 
295
                        $type = $arr[$i][3];
 
296
                        if ($ttype) { 
 
297
                                if ($isview) {
 
298
                                        if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
 
299
                                } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
 
300
                        } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
 
301
                }
 
302
                return $arr2;
 
303
        }
 
304
        
 
305
/*
 
306
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdatetime_data_type_changes.asp
 
307
/ SQL data type codes /
 
308
#define SQL_UNKNOWN_TYPE        0
 
309
#define SQL_CHAR                        1
 
310
#define SQL_NUMERIC              2
 
311
#define SQL_DECIMAL              3
 
312
#define SQL_INTEGER              4
 
313
#define SQL_SMALLINT            5
 
314
#define SQL_FLOAT                  6
 
315
#define SQL_REAL                        7
 
316
#define SQL_DOUBLE                8
 
317
#if (ODBCVER >= 0x0300)
 
318
#define SQL_DATETIME            9
 
319
#endif
 
320
#define SQL_VARCHAR             12
 
321
 
 
322
 
 
323
/ One-parameter shortcuts for date/time data types /
 
324
#if (ODBCVER >= 0x0300)
 
325
#define SQL_TYPE_DATE     91
 
326
#define SQL_TYPE_TIME     92
 
327
#define SQL_TYPE_TIMESTAMP 93
 
328
 
 
329
#define SQL_UNICODE                             (-95)
 
330
#define SQL_UNICODE_VARCHAR                     (-96)
 
331
#define SQL_UNICODE_LONGVARCHAR                 (-97)
 
332
*/
 
333
        function ODBCTypes($t)
 
334
        {
 
335
                switch ((integer)$t) {
 
336
                case 1: 
 
337
                case 12:
 
338
                case 0:
 
339
                case -95:
 
340
                case -96:
 
341
                        return 'C';
 
342
                case -97:
 
343
                case -1: //text
 
344
                        return 'X';
 
345
                case -4: //image
 
346
                        return 'B';
 
347
                                
 
348
                case 9: 
 
349
                case 91:
 
350
                        return 'D';
 
351
                
 
352
                case 10:
 
353
                case 11:
 
354
                case 92:
 
355
                case 93:
 
356
                        return 'T';
 
357
                        
 
358
                case 4:
 
359
                case 5:
 
360
                case -6:
 
361
                        return 'I';
 
362
                        
 
363
                case -11: // uniqidentifier
 
364
                        return 'R';
 
365
                case -7: //bit
 
366
                        return 'L';
 
367
                
 
368
                default:
 
369
                        return 'N';
 
370
                }
 
371
        }
 
372
        
 
373
        function &MetaColumns($table)
 
374
        {
 
375
        global $ADODB_FETCH_MODE;
 
376
        
 
377
                $false = false;
 
378
                if ($this->uCaseTables) $table = strtoupper($table);
 
379
                $schema = '';
 
380
                $this->_findschema($table,$schema);
 
381
                
 
382
                $savem = $ADODB_FETCH_MODE;
 
383
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 
384
        
 
385
                /*if (false) { // after testing, confirmed that the following does not work becoz of a bug
 
386
                        $qid2 = odbc_tables($this->_connectionID);
 
387
                        $rs = new ADORecordSet_odbc($qid2);             
 
388
                        $ADODB_FETCH_MODE = $savem;
 
389
                        if (!$rs) return false;
 
390
                        $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
 
391
                        $rs->_fetch();
 
392
                        
 
393
                        while (!$rs->EOF) {
 
394
                                if ($table == strtoupper($rs->fields[2])) {
 
395
                                        $q = $rs->fields[0];
 
396
                                        $o = $rs->fields[1];
 
397
                                        break;
 
398
                                }
 
399
                                $rs->MoveNext();
 
400
                        }
 
401
                        $rs->Close();
 
402
                        
 
403
                        $qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%');
 
404
                } */
 
405
                
 
406
                switch ($this->databaseType) {
 
407
                case 'access':
 
408
                case 'vfp':
 
409
                        $qid = odbc_columns($this->_connectionID);#,'%','',strtoupper($table),'%');
 
410
                        break;
 
411
                
 
412
                
 
413
                case 'db2':
 
414
            $colname = "%";
 
415
            $qid = odbc_columns($this->_connectionID, "", $schema, $table, $colname);
 
416
            break;
 
417
                        
 
418
                default:
 
419
                        $qid = @odbc_columns($this->_connectionID,'%','%',strtoupper($table),'%');
 
420
                        if (empty($qid)) $qid = odbc_columns($this->_connectionID);
 
421
                        break;
 
422
                }
 
423
                if (empty($qid)) return $false;
 
424
                
 
425
                $rs =& new ADORecordSet_odbc($qid);
 
426
                $ADODB_FETCH_MODE = $savem;
 
427
                
 
428
                if (!$rs) return $false;
 
429
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
 
430
                $rs->_fetch();
 
431
                
 
432
                $retarr = array();
 
433
                
 
434
                /*
 
435
                $rs->fields indices
 
436
                0 TABLE_QUALIFIER
 
437
                1 TABLE_SCHEM
 
438
                2 TABLE_NAME
 
439
                3 COLUMN_NAME
 
440
                4 DATA_TYPE
 
441
                5 TYPE_NAME
 
442
                6 PRECISION
 
443
                7 LENGTH
 
444
                8 SCALE
 
445
                9 RADIX
 
446
                10 NULLABLE
 
447
                11 REMARKS
 
448
                */
 
449
                while (!$rs->EOF) {
 
450
                //      adodb_pr($rs->fields);
 
451
                        if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
 
452
                                $fld = new ADOFieldObject();
 
453
                                $fld->name = $rs->fields[3];
 
454
                                $fld->type = $this->ODBCTypes($rs->fields[4]);
 
455
                                
 
456
                                // ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
 
457
                                // access uses precision to store length for char/varchar
 
458
                                if ($fld->type == 'C' or $fld->type == 'X') {
 
459
                                        if ($this->databaseType == 'access') 
 
460
                                                $fld->max_length = $rs->fields[6];
 
461
                                        else if ($rs->fields[4] <= -95) // UNICODE
 
462
                                                $fld->max_length = $rs->fields[7]/2;
 
463
                                        else
 
464
                                                $fld->max_length = $rs->fields[7];
 
465
                                } else 
 
466
                                        $fld->max_length = $rs->fields[7];
 
467
                                $fld->not_null = !empty($rs->fields[10]);
 
468
                                $fld->scale = $rs->fields[8];
 
469
                                $retarr[strtoupper($fld->name)] = $fld; 
 
470
                        } else if (sizeof($retarr)>0)
 
471
                                break;
 
472
                        $rs->MoveNext();
 
473
                }
 
474
                $rs->Close(); //-- crashes 4.03pl1 -- why?
 
475
                
 
476
                if (empty($retarr)) $retarr = false;
 
477
                return $retarr;
 
478
        }
 
479
        
 
480
        function Prepare($sql)
 
481
        {
 
482
                if (! $this->_bindInputArray) return $sql; // no binding
 
483
                $stmt = odbc_prepare($this->_connectionID,$sql);
 
484
                if (!$stmt) {
 
485
                        // we don't know whether odbc driver is parsing prepared stmts, so just return sql
 
486
                        return $sql;
 
487
                }
 
488
                return array($sql,$stmt,false);
 
489
        }
 
490
 
 
491
        /* returns queryID or false */
 
492
        function _query($sql,$inputarr=false) 
 
493
        {
 
494
        GLOBAL $php_errormsg;
 
495
                if (isset($php_errormsg)) $php_errormsg = '';
 
496
                $this->_error = '';
 
497
                
 
498
                if ($inputarr) {
 
499
                        if (is_array($sql)) {
 
500
                                $stmtid = $sql[1];
 
501
                        } else {
 
502
                                $stmtid = odbc_prepare($this->_connectionID,$sql);
 
503
        
 
504
                                if ($stmtid == false) {
 
505
                                        $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
 
506
                                        return false;
 
507
                                }
 
508
                        }
 
509
                        
 
510
                        if (! odbc_execute($stmtid,$inputarr)) {
 
511
                                //@odbc_free_result($stmtid);
 
512
                                if ($this->_haserrorfunctions) {
 
513
                                        $this->_errorMsg = odbc_errormsg();
 
514
                                        $this->_errorCode = odbc_error();
 
515
                                }
 
516
                                return false;
 
517
                        }
 
518
                
 
519
                } else if (is_array($sql)) {
 
520
                        $stmtid = $sql[1];
 
521
                        if (!odbc_execute($stmtid)) {
 
522
                                //@odbc_free_result($stmtid);
 
523
                                if ($this->_haserrorfunctions) {
 
524
                                        $this->_errorMsg = odbc_errormsg();
 
525
                                        $this->_errorCode = odbc_error();
 
526
                                }
 
527
                                return false;
 
528
                        }
 
529
                } else
 
530
                        $stmtid = odbc_exec($this->_connectionID,$sql);
 
531
                
 
532
                $this->_lastAffectedRows = 0;
 
533
                if ($stmtid) {
 
534
                        if (@odbc_num_fields($stmtid) == 0) {
 
535
                                $this->_lastAffectedRows = odbc_num_rows($stmtid);
 
536
                                $stmtid = true;
 
537
                        } else {
 
538
                                $this->_lastAffectedRows = 0;
 
539
                                odbc_binmode($stmtid,$this->binmode);
 
540
                                odbc_longreadlen($stmtid,$this->maxblobsize);
 
541
                        }
 
542
                        
 
543
                        if ($this->_haserrorfunctions) {
 
544
                                $this->_errorMsg = '';
 
545
                                $this->_errorCode = 0;
 
546
                        } else
 
547
                                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
 
548
                } else {
 
549
                        if ($this->_haserrorfunctions) {
 
550
                                $this->_errorMsg = odbc_errormsg();
 
551
                                $this->_errorCode = odbc_error();
 
552
                        } else
 
553
                                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
 
554
                }
 
555
                return $stmtid;
 
556
        }
 
557
 
 
558
        /*
 
559
                Insert a null into the blob field of the table first.
 
560
                Then use UpdateBlob to store the blob.
 
561
                
 
562
                Usage:
 
563
                 
 
564
                $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
 
565
                $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
 
566
        */
 
567
        function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
 
568
        {
 
569
                return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
 
570
        }
 
571
        
 
572
        // returns true or false
 
573
        function _close()
 
574
        {
 
575
                $ret = @odbc_close($this->_connectionID);
 
576
                $this->_connectionID = false;
 
577
                return $ret;
 
578
        }
 
579
 
 
580
        function _affectedrows()
 
581
        {
 
582
                return $this->_lastAffectedRows;
 
583
        }
 
584
        
 
585
}
 
586
        
 
587
/*--------------------------------------------------------------------------------------
 
588
         Class Name: Recordset
 
589
--------------------------------------------------------------------------------------*/
 
590
 
 
591
class ADORecordSet_odbc extends ADORecordSet {  
 
592
        
 
593
        var $bind = false;
 
594
        var $databaseType = "odbc";             
 
595
        var $dataProvider = "odbc";
 
596
        var $useFetchArray;
 
597
        var $_has_stupid_odbc_fetch_api_change;
 
598
        
 
599
        function ADORecordSet_odbc($id,$mode=false)
 
600
        {
 
601
                if ($mode === false) {  
 
602
                        global $ADODB_FETCH_MODE;
 
603
                        $mode = $ADODB_FETCH_MODE;
 
604
                }
 
605
                $this->fetchMode = $mode;
 
606
                
 
607
                $this->_queryID = $id;
 
608
                
 
609
                // the following is required for mysql odbc driver in 4.3.1 -- why?
 
610
                $this->EOF = false;
 
611
                $this->_currentRow = -1;
 
612
                //$this->ADORecordSet($id);
 
613
        }
 
614
 
 
615
 
 
616
        // returns the field object
 
617
        function &FetchField($fieldOffset = -1) 
 
618
        {
 
619
                
 
620
                $off=$fieldOffset+1; // offsets begin at 1
 
621
                
 
622
                $o= new ADOFieldObject();
 
623
                $o->name = @odbc_field_name($this->_queryID,$off);
 
624
                $o->type = @odbc_field_type($this->_queryID,$off);
 
625
                $o->max_length = @odbc_field_len($this->_queryID,$off);
 
626
                if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
 
627
                else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
 
628
                return $o;
 
629
        }
 
630
        
 
631
        /* Use associative array to get fields array */
 
632
        function Fields($colname)
 
633
        {
 
634
                if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
 
635
                if (!$this->bind) {
 
636
                        $this->bind = array();
 
637
                        for ($i=0; $i < $this->_numOfFields; $i++) {
 
638
                                $o = $this->FetchField($i);
 
639
                                $this->bind[strtoupper($o->name)] = $i;
 
640
                        }
 
641
                }
 
642
 
 
643
                 return $this->fields[$this->bind[strtoupper($colname)]];
 
644
        }
 
645
        
 
646
                
 
647
        function _initrs()
 
648
        {
 
649
        global $ADODB_COUNTRECS;
 
650
                $this->_numOfRows = ($ADODB_COUNTRECS) ? @odbc_num_rows($this->_queryID) : -1;
 
651
                $this->_numOfFields = @odbc_num_fields($this->_queryID);
 
652
                // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
 
653
                if ($this->_numOfRows == 0) $this->_numOfRows = -1;
 
654
                //$this->useFetchArray = $this->connection->useFetchArray;
 
655
                $this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
 
656
        }       
 
657
        
 
658
        function _seek($row)
 
659
        {
 
660
                return false;
 
661
        }
 
662
        
 
663
        // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
 
664
        function &GetArrayLimit($nrows,$offset=-1) 
 
665
        {
 
666
                if ($offset <= 0) {
 
667
                        $rs =& $this->GetArray($nrows);
 
668
                        return $rs;
 
669
                }
 
670
                $savem = $this->fetchMode;
 
671
                $this->fetchMode = ADODB_FETCH_NUM;
 
672
                $this->Move($offset);
 
673
                $this->fetchMode = $savem;
 
674
                
 
675
                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
 
676
                        $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
 
677
                }
 
678
                
 
679
                $results = array();
 
680
                $cnt = 0;
 
681
                while (!$this->EOF && $nrows != $cnt) {
 
682
                        $results[$cnt++] = $this->fields;
 
683
                        $this->MoveNext();
 
684
                }
 
685
                
 
686
                return $results;
 
687
        }
 
688
        
 
689
        
 
690
        function MoveNext() 
 
691
        {
 
692
                if ($this->_numOfRows != 0 && !$this->EOF) {            
 
693
                        $this->_currentRow++;
 
694
                        
 
695
                        if ($this->_has_stupid_odbc_fetch_api_change)
 
696
                                $rez = @odbc_fetch_into($this->_queryID,$this->fields);
 
697
                        else {
 
698
                                $row = 0;
 
699
                                $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
 
700
                        }
 
701
                        if ($rez) {
 
702
                                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
 
703
                                        $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
 
704
                                }
 
705
                                return true;
 
706
                        }
 
707
                }
 
708
                $this->fields = false;
 
709
                $this->EOF = true;
 
710
                return false;
 
711
        }       
 
712
        
 
713
        function _fetch()
 
714
        {
 
715
 
 
716
                if ($this->_has_stupid_odbc_fetch_api_change)
 
717
                        $rez = @odbc_fetch_into($this->_queryID,$this->fields);
 
718
                else {
 
719
                        $row = 0;
 
720
                        $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
 
721
                }
 
722
                if ($rez) {
 
723
                        if ($this->fetchMode & ADODB_FETCH_ASSOC) {
 
724
                                $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
 
725
                        }
 
726
                        return true;
 
727
                }
 
728
                $this->fields = false;
 
729
                return false;
 
730
        }
 
731
        
 
732
        function _close() 
 
733
        {
 
734
                return @odbc_free_result($this->_queryID);              
 
735
        }
 
736
 
 
737
}
 
738
?>
 
 
b'\\ No newline at end of file'