1 | <?php
|
---|
2 | /*
|
---|
3 | V4.94 23 Jan 2007 (c) 2000-2007 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. See License.txt.
|
---|
7 | Set tabs to 4 for best viewing.
|
---|
8 | Latest version is available at http://adodb.sourceforge.net
|
---|
9 | */
|
---|
10 | // Code contributed by "stefan bogdan" <sbogdan#rsb.ro>
|
---|
11 |
|
---|
12 | // security - hide paths
|
---|
13 | if (!defined('ADODB_DIR')) die();
|
---|
14 |
|
---|
15 | define("_ADODB_ODBTP_LAYER", 2 );
|
---|
16 |
|
---|
17 | class ADODB_odbtp extends ADOConnection{
|
---|
18 | var $databaseType = "odbtp";
|
---|
19 | var $dataProvider = "odbtp";
|
---|
20 | var $fmtDate = "'Y-m-d'";
|
---|
21 | var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
|
---|
22 | var $replaceQuote = "''"; // string to use to replace quotes
|
---|
23 | var $odbc_driver = 0;
|
---|
24 | var $hasAffectedRows = true;
|
---|
25 | var $hasInsertID = false;
|
---|
26 | var $hasGenID = true;
|
---|
27 | var $hasMoveFirst = true;
|
---|
28 |
|
---|
29 | var $_genSeqSQL = "create table %s (seq_name char(30) not null unique , seq_value integer not null)";
|
---|
30 | var $_dropSeqSQL = "delete from adodb_seq where seq_name = '%s'";
|
---|
31 | var $_bindInputArray = false;
|
---|
32 | var $_useUnicodeSQL = false;
|
---|
33 | var $_canPrepareSP = false;
|
---|
34 | var $_dontPoolDBC = true;
|
---|
35 |
|
---|
36 | function ADODB_odbtp()
|
---|
37 | {
|
---|
38 | }
|
---|
39 |
|
---|
40 | function ServerInfo()
|
---|
41 | {
|
---|
42 | return array('description' => @odbtp_get_attr( ODB_ATTR_DBMSNAME, $this->_connectionID),
|
---|
43 | 'version' => @odbtp_get_attr( ODB_ATTR_DBMSVER, $this->_connectionID));
|
---|
44 | }
|
---|
45 |
|
---|
46 | function ErrorMsg()
|
---|
47 | {
|
---|
48 | if (empty($this->_connectionID)) return @odbtp_last_error();
|
---|
49 | return @odbtp_last_error($this->_connectionID);
|
---|
50 | }
|
---|
51 |
|
---|
52 | function ErrorNo()
|
---|
53 | {
|
---|
54 | if (empty($this->_connectionID)) return @odbtp_last_error_state();
|
---|
55 | return @odbtp_last_error_state($this->_connectionID);
|
---|
56 | }
|
---|
57 |
|
---|
58 | function _insertid()
|
---|
59 | {
|
---|
60 | // SCOPE_IDENTITY()
|
---|
61 | // Returns the last IDENTITY value inserted into an IDENTITY column in
|
---|
62 | // the same scope. A scope is a module -- a stored procedure, trigger,
|
---|
63 | // function, or batch. Thus, two statements are in the same scope if
|
---|
64 | // they are in the same stored procedure, function, or batch.
|
---|
65 | return $this->GetOne($this->identitySQL);
|
---|
66 | }
|
---|
67 |
|
---|
68 | function _affectedrows()
|
---|
69 | {
|
---|
70 | if ($this->_queryID) {
|
---|
71 | return @odbtp_affected_rows ($this->_queryID);
|
---|
72 | } else
|
---|
73 | return 0;
|
---|
74 | }
|
---|
75 |
|
---|
76 | function CreateSequence($seqname='adodbseq',$start=1)
|
---|
77 | {
|
---|
78 | //verify existence
|
---|
79 | $num = $this->GetOne("select seq_value from adodb_seq");
|
---|
80 | $seqtab='adodb_seq';
|
---|
81 | if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
|
---|
82 | $path = @odbtp_get_attr( ODB_ATTR_DATABASENAME, $this->_connectionID );
|
---|
83 | //if using vfp dbc file
|
---|
84 | if( !strcasecmp(strrchr($path, '.'), '.dbc') )
|
---|
85 | $path = substr($path,0,strrpos($path,'\/'));
|
---|
86 | $seqtab = $path . '/' . $seqtab;
|
---|
87 | }
|
---|
88 | if($num == false) {
|
---|
89 | if (empty($this->_genSeqSQL)) return false;
|
---|
90 | $ok = $this->Execute(sprintf($this->_genSeqSQL ,$seqtab));
|
---|
91 | }
|
---|
92 | $num = $this->GetOne("select seq_value from adodb_seq where seq_name='$seqname'");
|
---|
93 | if ($num) {
|
---|
94 | return false;
|
---|
95 | }
|
---|
96 | $start -= 1;
|
---|
97 | return $this->Execute("insert into adodb_seq values('$seqname',$start)");
|
---|
98 | }
|
---|
99 |
|
---|
100 | function DropSequence($seqname)
|
---|
101 | {
|
---|
102 | if (empty($this->_dropSeqSQL)) return false;
|
---|
103 | return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
|
---|
104 | }
|
---|
105 |
|
---|
106 | function GenID($seq='adodbseq',$start=1)
|
---|
107 | {
|
---|
108 | $seqtab='adodb_seq';
|
---|
109 | if( $this->odbc_driver == ODB_DRIVER_FOXPRO) {
|
---|
110 | $path = @odbtp_get_attr( ODB_ATTR_DATABASENAME, $this->_connectionID );
|
---|
111 | //if using vfp dbc file
|
---|
112 | if( !strcasecmp(strrchr($path, '.'), '.dbc') )
|
---|
113 | $path = substr($path,0,strrpos($path,'\/'));
|
---|
114 | $seqtab = $path . '/' . $seqtab;
|
---|
115 | }
|
---|
116 | $MAXLOOPS = 100;
|
---|
117 | while (--$MAXLOOPS>=0) {
|
---|
118 | $num = $this->GetOne("select seq_value from adodb_seq where seq_name='$seq'");
|
---|
119 | if ($num === false) {
|
---|
120 | //verify if abodb_seq table exist
|
---|
121 | $ok = $this->GetOne("select seq_value from adodb_seq ");
|
---|
122 | if(!$ok) {
|
---|
123 | //creating the sequence table adodb_seq
|
---|
124 | $this->Execute(sprintf($this->_genSeqSQL ,$seqtab));
|
---|
125 | }
|
---|
126 | $start -= 1;
|
---|
127 | $num = '0';
|
---|
128 | $ok = $this->Execute("insert into adodb_seq values('$seq',$start)");
|
---|
129 | if (!$ok) return false;
|
---|
130 | }
|
---|
131 | $ok = $this->Execute("update adodb_seq set seq_value=seq_value+1 where seq_name='$seq'");
|
---|
132 | if($ok) {
|
---|
133 | $num += 1;
|
---|
134 | $this->genID = $num;
|
---|
135 | return $num;
|
---|
136 | }
|
---|
137 | }
|
---|
138 | if ($fn = $this->raiseErrorFn) {
|
---|
139 | $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
|
---|
140 | }
|
---|
141 | return false;
|
---|
142 | }
|
---|
143 |
|
---|
144 | //example for $UserOrDSN
|
---|
145 | //for visual fox : DRIVER={Microsoft Visual FoxPro Driver};SOURCETYPE=DBF;SOURCEDB=c:\YourDbfFileDir;EXCLUSIVE=NO;
|
---|
146 | //for visual fox dbc: DRIVER={Microsoft Visual FoxPro Driver};SOURCETYPE=DBC;SOURCEDB=c:\YourDbcFileDir\mydb.dbc;EXCLUSIVE=NO;
|
---|
147 | //for access : DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\path_to_access_db\base_test.mdb;UID=root;PWD=;
|
---|
148 | //for mssql : DRIVER={SQL Server};SERVER=myserver;UID=myuid;PWD=mypwd;DATABASE=OdbtpTest;
|
---|
149 | //if uid & pwd can be separate
|
---|
150 | function _connect($HostOrInterface, $UserOrDSN='', $argPassword='', $argDatabase='')
|
---|
151 | {
|
---|
152 | $this->_connectionID = odbtp_connect($HostOrInterface,$UserOrDSN,$argPassword,$argDatabase);
|
---|
153 | if ($this->_connectionID === false) {
|
---|
154 | $this->_errorMsg = $this->ErrorMsg() ;
|
---|
155 | return false;
|
---|
156 | }
|
---|
157 |
|
---|
158 | odbtp_convert_datetime($this->_connectionID,true);
|
---|
159 |
|
---|
160 | if ($this->_dontPoolDBC) {
|
---|
161 | if (function_exists('odbtp_dont_pool_dbc'))
|
---|
162 | @odbtp_dont_pool_dbc($this->_connectionID);
|
---|
163 | }
|
---|
164 | else {
|
---|
165 | $this->_dontPoolDBC = true;
|
---|
166 | }
|
---|
167 | $this->odbc_driver = @odbtp_get_attr(ODB_ATTR_DRIVER, $this->_connectionID);
|
---|
168 | $dbms = strtolower(@odbtp_get_attr(ODB_ATTR_DBMSNAME, $this->_connectionID));
|
---|
169 | $this->odbc_name = $dbms;
|
---|
170 |
|
---|
171 | // Account for inconsistent DBMS names
|
---|
172 | if( $this->odbc_driver == ODB_DRIVER_ORACLE )
|
---|
173 | $dbms = 'oracle';
|
---|
174 | else if( $this->odbc_driver == ODB_DRIVER_SYBASE )
|
---|
175 | $dbms = 'sybase';
|
---|
176 |
|
---|
177 | // Set DBMS specific attributes
|
---|
178 | switch( $dbms ) {
|
---|
179 | case 'microsoft sql server':
|
---|
180 | $this->databaseType = 'odbtp_mssql';
|
---|
181 | $this->fmtDate = "'Y-m-d'";
|
---|
182 | $this->fmtTimeStamp = "'Y-m-d h:i:sA'";
|
---|
183 | $this->sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
---|
184 | $this->sysTimeStamp = 'GetDate()';
|
---|
185 | $this->ansiOuter = true;
|
---|
186 | $this->leftOuter = '*=';
|
---|
187 | $this->rightOuter = '=*';
|
---|
188 | $this->hasTop = 'top';
|
---|
189 | $this->hasInsertID = true;
|
---|
190 | $this->hasTransactions = true;
|
---|
191 | $this->_bindInputArray = true;
|
---|
192 | $this->_canSelectDb = true;
|
---|
193 | $this->substr = "substring";
|
---|
194 | $this->length = 'len';
|
---|
195 | $this->identitySQL = 'select @@IDENTITY';
|
---|
196 | $this->metaDatabasesSQL = "select name from master..sysdatabases where name <> 'master'";
|
---|
197 | $this->_canPrepareSP = true;
|
---|
198 | break;
|
---|
199 | case 'access':
|
---|
200 | $this->databaseType = 'odbtp_access';
|
---|
201 | $this->fmtDate = "#Y-m-d#";
|
---|
202 | $this->fmtTimeStamp = "#Y-m-d h:i:sA#";
|
---|
203 | $this->sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
|
---|
204 | $this->sysTimeStamp = 'NOW';
|
---|
205 | $this->hasTop = 'top';
|
---|
206 | $this->hasTransactions = false;
|
---|
207 | $this->_canPrepareSP = true; // For MS Access only.
|
---|
208 | break;
|
---|
209 | case 'visual foxpro':
|
---|
210 | $this->databaseType = 'odbtp_vfp';
|
---|
211 | $this->fmtDate = "{^Y-m-d}";
|
---|
212 | $this->fmtTimeStamp = "{^Y-m-d, h:i:sA}";
|
---|
213 | $this->sysDate = 'date()';
|
---|
214 | $this->sysTimeStamp = 'datetime()';
|
---|
215 | $this->ansiOuter = true;
|
---|
216 | $this->hasTop = 'top';
|
---|
217 | $this->hasTransactions = false;
|
---|
218 | $this->replaceQuote = "'+chr(39)+'";
|
---|
219 | $this->true = '.T.';
|
---|
220 | $this->false = '.F.';
|
---|
221 |
|
---|
222 | break;
|
---|
223 | case 'oracle':
|
---|
224 | $this->databaseType = 'odbtp_oci8';
|
---|
225 | $this->fmtDate = "'Y-m-d 00:00:00'";
|
---|
226 | $this->fmtTimeStamp = "'Y-m-d h:i:sA'";
|
---|
227 | $this->sysDate = 'TRUNC(SYSDATE)';
|
---|
228 | $this->sysTimeStamp = 'SYSDATE';
|
---|
229 | $this->hasTransactions = true;
|
---|
230 | $this->_bindInputArray = true;
|
---|
231 | $this->concat_operator = '||';
|
---|
232 | break;
|
---|
233 | case 'sybase':
|
---|
234 | $this->databaseType = 'odbtp_sybase';
|
---|
235 | $this->fmtDate = "'Y-m-d'";
|
---|
236 | $this->fmtTimeStamp = "'Y-m-d H:i:s'";
|
---|
237 | $this->sysDate = 'GetDate()';
|
---|
238 | $this->sysTimeStamp = 'GetDate()';
|
---|
239 | $this->leftOuter = '*=';
|
---|
240 | $this->rightOuter = '=*';
|
---|
241 | $this->hasInsertID = true;
|
---|
242 | $this->hasTransactions = true;
|
---|
243 | $this->identitySQL = 'select @@IDENTITY';
|
---|
244 | break;
|
---|
245 | default:
|
---|
246 | $this->databaseType = 'odbtp';
|
---|
247 | if( @odbtp_get_attr(ODB_ATTR_TXNCAPABLE, $this->_connectionID) )
|
---|
248 | $this->hasTransactions = true;
|
---|
249 | else
|
---|
250 | $this->hasTransactions = false;
|
---|
251 | }
|
---|
252 | @odbtp_set_attr(ODB_ATTR_FULLCOLINFO, TRUE, $this->_connectionID );
|
---|
253 |
|
---|
254 | if ($this->_useUnicodeSQL )
|
---|
255 | @odbtp_set_attr(ODB_ATTR_UNICODESQL, TRUE, $this->_connectionID);
|
---|
256 |
|
---|
257 | return true;
|
---|
258 | }
|
---|
259 |
|
---|
260 | function _pconnect($HostOrInterface, $UserOrDSN='', $argPassword='', $argDatabase='')
|
---|
261 | {
|
---|
262 | $this->_dontPoolDBC = false;
|
---|
263 | return $this->_connect($HostOrInterface, $UserOrDSN, $argPassword, $argDatabase);
|
---|
264 | }
|
---|
265 |
|
---|
266 | function SelectDB($dbName)
|
---|
267 | {
|
---|
268 | if (!@odbtp_select_db($dbName, $this->_connectionID)) {
|
---|
269 | return false;
|
---|
270 | }
|
---|
271 | $this->database = $dbName;
|
---|
272 | $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
|
---|
273 | return true;
|
---|
274 | }
|
---|
275 |
|
---|
276 | function &MetaTables($ttype='',$showSchema=false,$mask=false)
|
---|
277 | {
|
---|
278 | global $ADODB_FETCH_MODE;
|
---|
279 |
|
---|
280 | $savem = $ADODB_FETCH_MODE;
|
---|
281 | $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
---|
282 | if ($this->fetchMode !== false) $savefm = $this->SetFetchMode(false);
|
---|
283 |
|
---|
284 | $arr =& $this->GetArray("||SQLTables||||$ttype");
|
---|
285 |
|
---|
286 | if (isset($savefm)) $this->SetFetchMode($savefm);
|
---|
287 | $ADODB_FETCH_MODE = $savem;
|
---|
288 |
|
---|
289 | $arr2 = array();
|
---|
290 | for ($i=0; $i < sizeof($arr); $i++) {
|
---|
291 | if ($arr[$i][3] == 'SYSTEM TABLE' ) continue;
|
---|
292 | if ($arr[$i][2])
|
---|
293 | $arr2[] = $showSchema && $arr[$i][1]? $arr[$i][1].'.'.$arr[$i][2] : $arr[$i][2];
|
---|
294 | }
|
---|
295 | return $arr2;
|
---|
296 | }
|
---|
297 |
|
---|
298 | function &MetaColumns($table,$upper=true)
|
---|
299 | {
|
---|
300 | global $ADODB_FETCH_MODE;
|
---|
301 |
|
---|
302 | $schema = false;
|
---|
303 | $this->_findschema($table,$schema);
|
---|
304 | if ($upper) $table = strtoupper($table);
|
---|
305 |
|
---|
306 | $savem = $ADODB_FETCH_MODE;
|
---|
307 | $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
---|
308 | if ($this->fetchMode !== false) $savefm = $this->SetFetchMode(false);
|
---|
309 |
|
---|
310 | $rs = $this->Execute( "||SQLColumns||$schema|$table" );
|
---|
311 |
|
---|
312 | if (isset($savefm)) $this->SetFetchMode($savefm);
|
---|
313 | $ADODB_FETCH_MODE = $savem;
|
---|
314 |
|
---|
315 | if (!$rs || $rs->EOF) {
|
---|
316 | $false = false;
|
---|
317 | return $false;
|
---|
318 | }
|
---|
319 | $retarr = array();
|
---|
320 | while (!$rs->EOF) {
|
---|
321 | //print_r($rs->fields);
|
---|
322 | if (strtoupper($rs->fields[2]) == $table) {
|
---|
323 | $fld = new ADOFieldObject();
|
---|
324 | $fld->name = $rs->fields[3];
|
---|
325 | $fld->type = $rs->fields[5];
|
---|
326 | $fld->max_length = $rs->fields[6];
|
---|
327 | $fld->not_null = !empty($rs->fields[9]);
|
---|
328 | $fld->scale = $rs->fields[7];
|
---|
329 | if (isset($rs->fields[12])) // vfp does not have field 12
|
---|
330 | if (!is_null($rs->fields[12])) {
|
---|
331 | $fld->has_default = true;
|
---|
332 | $fld->default_value = $rs->fields[12];
|
---|
333 | }
|
---|
334 | $retarr[strtoupper($fld->name)] = $fld;
|
---|
335 | } else if (!empty($retarr))
|
---|
336 | break;
|
---|
337 | $rs->MoveNext();
|
---|
338 | }
|
---|
339 | $rs->Close();
|
---|
340 |
|
---|
341 | return $retarr;
|
---|
342 | }
|
---|
343 |
|
---|
344 | function &MetaPrimaryKeys($table, $owner='')
|
---|
345 | {
|
---|
346 | global $ADODB_FETCH_MODE;
|
---|
347 |
|
---|
348 | $savem = $ADODB_FETCH_MODE;
|
---|
349 | $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
---|
350 | $arr =& $this->GetArray("||SQLPrimaryKeys||$owner|$table");
|
---|
351 | $ADODB_FETCH_MODE = $savem;
|
---|
352 |
|
---|
353 | //print_r($arr);
|
---|
354 | $arr2 = array();
|
---|
355 | for ($i=0; $i < sizeof($arr); $i++) {
|
---|
356 | if ($arr[$i][3]) $arr2[] = $arr[$i][3];
|
---|
357 | }
|
---|
358 | return $arr2;
|
---|
359 | }
|
---|
360 |
|
---|
361 | function &MetaForeignKeys($table, $owner='', $upper=false)
|
---|
362 | {
|
---|
363 | global $ADODB_FETCH_MODE;
|
---|
364 |
|
---|
365 | $savem = $ADODB_FETCH_MODE;
|
---|
366 | $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
---|
367 | $constraints =& $this->GetArray("||SQLForeignKeys|||||$owner|$table");
|
---|
368 | $ADODB_FETCH_MODE = $savem;
|
---|
369 |
|
---|
370 | $arr = false;
|
---|
371 | foreach($constraints as $constr) {
|
---|
372 | //print_r($constr);
|
---|
373 | $arr[$constr[11]][$constr[2]][] = $constr[7].'='.$constr[3];
|
---|
374 | }
|
---|
375 | if (!$arr) {
|
---|
376 | $false = false;
|
---|
377 | return $false;
|
---|
378 | }
|
---|
379 |
|
---|
380 | $arr2 = array();
|
---|
381 |
|
---|
382 | foreach($arr as $k => $v) {
|
---|
383 | foreach($v as $a => $b) {
|
---|
384 | if ($upper) $a = strtoupper($a);
|
---|
385 | $arr2[$a] = $b;
|
---|
386 | }
|
---|
387 | }
|
---|
388 | return $arr2;
|
---|
389 | }
|
---|
390 |
|
---|
391 | function BeginTrans()
|
---|
392 | {
|
---|
393 | if (!$this->hasTransactions) return false;
|
---|
394 | if ($this->transOff) return true;
|
---|
395 | $this->transCnt += 1;
|
---|
396 | $this->autoCommit = false;
|
---|
397 | if (defined('ODB_TXN_DEFAULT'))
|
---|
398 | $txn = ODB_TXN_DEFAULT;
|
---|
399 | else
|
---|
400 | $txn = ODB_TXN_READUNCOMMITTED;
|
---|
401 | $rs = @odbtp_set_attr(ODB_ATTR_TRANSACTIONS,$txn,$this->_connectionID);
|
---|
402 | if(!$rs) return false;
|
---|
403 | return true;
|
---|
404 | }
|
---|
405 |
|
---|
406 | function CommitTrans($ok=true)
|
---|
407 | {
|
---|
408 | if ($this->transOff) return true;
|
---|
409 | if (!$ok) return $this->RollbackTrans();
|
---|
410 | if ($this->transCnt) $this->transCnt -= 1;
|
---|
411 | $this->autoCommit = true;
|
---|
412 | if( ($ret = @odbtp_commit($this->_connectionID)) )
|
---|
413 | $ret = @odbtp_set_attr(ODB_ATTR_TRANSACTIONS, ODB_TXN_NONE, $this->_connectionID);//set transaction off
|
---|
414 | return $ret;
|
---|
415 | }
|
---|
416 |
|
---|
417 | function RollbackTrans()
|
---|
418 | {
|
---|
419 | if ($this->transOff) return true;
|
---|
420 | if ($this->transCnt) $this->transCnt -= 1;
|
---|
421 | $this->autoCommit = true;
|
---|
422 | if( ($ret = @odbtp_rollback($this->_connectionID)) )
|
---|
423 | $ret = @odbtp_set_attr(ODB_ATTR_TRANSACTIONS, ODB_TXN_NONE, $this->_connectionID);//set transaction off
|
---|
424 | return $ret;
|
---|
425 | }
|
---|
426 |
|
---|
427 | function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
|
---|
428 | {
|
---|
429 | // TOP requires ORDER BY for Visual FoxPro
|
---|
430 | if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
|
---|
431 | if (!preg_match('/ORDER[ \t\r\n]+BY/is',$sql)) $sql .= ' ORDER BY 1';
|
---|
432 | }
|
---|
433 | $ret =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
|
---|
434 | return $ret;
|
---|
435 | }
|
---|
436 |
|
---|
437 | function Prepare($sql)
|
---|
438 | {
|
---|
439 | if (! $this->_bindInputArray) return $sql; // no binding
|
---|
440 | $stmt = @odbtp_prepare($sql,$this->_connectionID);
|
---|
441 | if (!$stmt) {
|
---|
442 | // print "Prepare Error for ($sql) ".$this->ErrorMsg()."<br>";
|
---|
443 | return $sql;
|
---|
444 | }
|
---|
445 | return array($sql,$stmt,false);
|
---|
446 | }
|
---|
447 |
|
---|
448 | function PrepareSP($sql)
|
---|
449 | {
|
---|
450 | if (!$this->_canPrepareSP) return $sql; // Can't prepare procedures
|
---|
451 |
|
---|
452 | $stmt = @odbtp_prepare_proc($sql,$this->_connectionID);
|
---|
453 | if (!$stmt) return false;
|
---|
454 | return array($sql,$stmt);
|
---|
455 | }
|
---|
456 |
|
---|
457 | /*
|
---|
458 | Usage:
|
---|
459 | $stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
|
---|
460 |
|
---|
461 | # note that the parameter does not have @ in front!
|
---|
462 | $db->Parameter($stmt,$id,'myid');
|
---|
463 | $db->Parameter($stmt,$group,'group',false,64);
|
---|
464 | $db->Parameter($stmt,$group,'photo',false,100000,ODB_BINARY);
|
---|
465 | $db->Execute($stmt);
|
---|
466 |
|
---|
467 | @param $stmt Statement returned by Prepare() or PrepareSP().
|
---|
468 | @param $var PHP variable to bind to. Can set to null (for isNull support).
|
---|
469 | @param $name Name of stored procedure variable name to bind to.
|
---|
470 | @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in odbtp.
|
---|
471 | @param [$maxLen] Holds an maximum length of the variable.
|
---|
472 | @param [$type] The data type of $var. Legal values depend on driver.
|
---|
473 |
|
---|
474 | See odbtp_attach_param documentation at http://odbtp.sourceforge.net.
|
---|
475 | */
|
---|
476 | function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=0, $type=0)
|
---|
477 | {
|
---|
478 | if ( $this->odbc_driver == ODB_DRIVER_JET ) {
|
---|
479 | $name = '['.$name.']';
|
---|
480 | if( !$type && $this->_useUnicodeSQL
|
---|
481 | && @odbtp_param_bindtype($stmt[1], $name) == ODB_CHAR )
|
---|
482 | {
|
---|
483 | $type = ODB_WCHAR;
|
---|
484 | }
|
---|
485 | }
|
---|
486 | else {
|
---|
487 | $name = '@'.$name;
|
---|
488 | }
|
---|
489 | return @odbtp_attach_param($stmt[1], $name, $var, $type, $maxLen);
|
---|
490 | }
|
---|
491 |
|
---|
492 | /*
|
---|
493 | Insert a null into the blob field of the table first.
|
---|
494 | Then use UpdateBlob to store the blob.
|
---|
495 |
|
---|
496 | Usage:
|
---|
497 |
|
---|
498 | $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
|
---|
499 | $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
|
---|
500 | */
|
---|
501 |
|
---|
502 | function UpdateBlob($table,$column,$val,$where,$blobtype='image')
|
---|
503 | {
|
---|
504 | $sql = "UPDATE $table SET $column = ? WHERE $where";
|
---|
505 | if( !($stmt = @odbtp_prepare($sql, $this->_connectionID)) )
|
---|
506 | return false;
|
---|
507 | if( !@odbtp_input( $stmt, 1, ODB_BINARY, 1000000, $blobtype ) )
|
---|
508 | return false;
|
---|
509 | if( !@odbtp_set( $stmt, 1, $val ) )
|
---|
510 | return false;
|
---|
511 | return @odbtp_execute( $stmt ) != false;
|
---|
512 | }
|
---|
513 |
|
---|
514 | function IfNull( $field, $ifNull )
|
---|
515 | {
|
---|
516 | switch( $this->odbc_driver ) {
|
---|
517 | case ODB_DRIVER_MSSQL:
|
---|
518 | return " ISNULL($field, $ifNull) ";
|
---|
519 | case ODB_DRIVER_JET:
|
---|
520 | return " IIF(IsNull($field), $ifNull, $field) ";
|
---|
521 | }
|
---|
522 | return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
|
---|
523 | }
|
---|
524 |
|
---|
525 | function _query($sql,$inputarr=false)
|
---|
526 | {
|
---|
527 | global $php_errormsg;
|
---|
528 |
|
---|
529 | if ($inputarr) {
|
---|
530 | if (is_array($sql)) {
|
---|
531 | $stmtid = $sql[1];
|
---|
532 | } else {
|
---|
533 | $stmtid = @odbtp_prepare($sql,$this->_connectionID);
|
---|
534 | if ($stmtid == false) {
|
---|
535 | $this->_errorMsg = $php_errormsg;
|
---|
536 | return false;
|
---|
537 | }
|
---|
538 | }
|
---|
539 | $num_params = @odbtp_num_params( $stmtid );
|
---|
540 | for( $param = 1; $param <= $num_params; $param++ ) {
|
---|
541 | @odbtp_input( $stmtid, $param );
|
---|
542 | @odbtp_set( $stmtid, $param, $inputarr[$param-1] );
|
---|
543 | }
|
---|
544 | if (!@odbtp_execute($stmtid) ) {
|
---|
545 | return false;
|
---|
546 | }
|
---|
547 | } else if (is_array($sql)) {
|
---|
548 | $stmtid = $sql[1];
|
---|
549 | if (!@odbtp_execute($stmtid)) {
|
---|
550 | return false;
|
---|
551 | }
|
---|
552 | } else {
|
---|
553 | $stmtid = odbtp_query($sql,$this->_connectionID);
|
---|
554 | }
|
---|
555 | $this->_lastAffectedRows = 0;
|
---|
556 | if ($stmtid) {
|
---|
557 | $this->_lastAffectedRows = @odbtp_affected_rows($stmtid);
|
---|
558 | }
|
---|
559 | return $stmtid;
|
---|
560 | }
|
---|
561 |
|
---|
562 | function _close()
|
---|
563 | {
|
---|
564 | $ret = @odbtp_close($this->_connectionID);
|
---|
565 | $this->_connectionID = false;
|
---|
566 | return $ret;
|
---|
567 | }
|
---|
568 | }
|
---|
569 |
|
---|
570 | class ADORecordSet_odbtp extends ADORecordSet {
|
---|
571 |
|
---|
572 | var $databaseType = 'odbtp';
|
---|
573 | var $canSeek = true;
|
---|
574 |
|
---|
575 | function ADORecordSet_odbtp($queryID,$mode=false)
|
---|
576 | {
|
---|
577 | if ($mode === false) {
|
---|
578 | global $ADODB_FETCH_MODE;
|
---|
579 | $mode = $ADODB_FETCH_MODE;
|
---|
580 | }
|
---|
581 | $this->fetchMode = $mode;
|
---|
582 | $this->ADORecordSet($queryID);
|
---|
583 | }
|
---|
584 |
|
---|
585 | function _initrs()
|
---|
586 | {
|
---|
587 | $this->_numOfFields = @odbtp_num_fields($this->_queryID);
|
---|
588 | if (!($this->_numOfRows = @odbtp_num_rows($this->_queryID)))
|
---|
589 | $this->_numOfRows = -1;
|
---|
590 |
|
---|
591 | if (!$this->connection->_useUnicodeSQL) return;
|
---|
592 |
|
---|
593 | if ($this->connection->odbc_driver == ODB_DRIVER_JET) {
|
---|
594 | if (!@odbtp_get_attr(ODB_ATTR_MAPCHARTOWCHAR,
|
---|
595 | $this->connection->_connectionID))
|
---|
596 | {
|
---|
597 | for ($f = 0; $f < $this->_numOfFields; $f++) {
|
---|
598 | if (@odbtp_field_bindtype($this->_queryID, $f) == ODB_CHAR)
|
---|
599 | @odbtp_bind_field($this->_queryID, $f, ODB_WCHAR);
|
---|
600 | }
|
---|
601 | }
|
---|
602 | }
|
---|
603 | }
|
---|
604 |
|
---|
605 | function &FetchField($fieldOffset = 0)
|
---|
606 | {
|
---|
607 | $off=$fieldOffset; // offsets begin at 0
|
---|
608 | $o= new ADOFieldObject();
|
---|
609 | $o->name = @odbtp_field_name($this->_queryID,$off);
|
---|
610 | $o->type = @odbtp_field_type($this->_queryID,$off);
|
---|
611 | $o->max_length = @odbtp_field_length($this->_queryID,$off);
|
---|
612 | if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
|
---|
613 | else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
|
---|
614 | return $o;
|
---|
615 | }
|
---|
616 |
|
---|
617 | function _seek($row)
|
---|
618 | {
|
---|
619 | return @odbtp_data_seek($this->_queryID, $row);
|
---|
620 | }
|
---|
621 |
|
---|
622 | function fields($colname)
|
---|
623 | {
|
---|
624 | if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
|
---|
625 |
|
---|
626 | if (!$this->bind) {
|
---|
627 | $this->bind = array();
|
---|
628 | for ($i=0; $i < $this->_numOfFields; $i++) {
|
---|
629 | $name = @odbtp_field_name( $this->_queryID, $i );
|
---|
630 | $this->bind[strtoupper($name)] = $i;
|
---|
631 | }
|
---|
632 | }
|
---|
633 | return $this->fields[$this->bind[strtoupper($colname)]];
|
---|
634 | }
|
---|
635 |
|
---|
636 | function _fetch_odbtp($type=0)
|
---|
637 | {
|
---|
638 | switch ($this->fetchMode) {
|
---|
639 | case ADODB_FETCH_NUM:
|
---|
640 | $this->fields = @odbtp_fetch_row($this->_queryID, $type);
|
---|
641 | break;
|
---|
642 | case ADODB_FETCH_ASSOC:
|
---|
643 | $this->fields = @odbtp_fetch_assoc($this->_queryID, $type);
|
---|
644 | break;
|
---|
645 | default:
|
---|
646 | $this->fields = @odbtp_fetch_array($this->_queryID, $type);
|
---|
647 | }
|
---|
648 | if ($this->databaseType = 'odbtp_vfp') {
|
---|
649 | if ($this->fields)
|
---|
650 | foreach($this->fields as $k => $v) {
|
---|
651 | if (strncmp($v,'1899-12-30',10) == 0) $this->fields[$k] = '';
|
---|
652 | }
|
---|
653 | }
|
---|
654 | return is_array($this->fields);
|
---|
655 | }
|
---|
656 |
|
---|
657 | function _fetch()
|
---|
658 | {
|
---|
659 | return $this->_fetch_odbtp();
|
---|
660 | }
|
---|
661 |
|
---|
662 | function MoveFirst()
|
---|
663 | {
|
---|
664 | if (!$this->_fetch_odbtp(ODB_FETCH_FIRST)) return false;
|
---|
665 | $this->EOF = false;
|
---|
666 | $this->_currentRow = 0;
|
---|
667 | return true;
|
---|
668 | }
|
---|
669 |
|
---|
670 | function MoveLast()
|
---|
671 | {
|
---|
672 | if (!$this->_fetch_odbtp(ODB_FETCH_LAST)) return false;
|
---|
673 | $this->EOF = false;
|
---|
674 | $this->_currentRow = $this->_numOfRows - 1;
|
---|
675 | return true;
|
---|
676 | }
|
---|
677 |
|
---|
678 | function NextRecordSet()
|
---|
679 | {
|
---|
680 | if (!@odbtp_next_result($this->_queryID)) return false;
|
---|
681 | $this->_inited = false;
|
---|
682 | $this->bind = false;
|
---|
683 | $this->_currentRow = -1;
|
---|
684 | $this->Init();
|
---|
685 | return true;
|
---|
686 | }
|
---|
687 |
|
---|
688 | function _close()
|
---|
689 | {
|
---|
690 | return @odbtp_free_query($this->_queryID);
|
---|
691 | }
|
---|
692 | }
|
---|
693 |
|
---|
694 | class ADORecordSet_odbtp_mssql extends ADORecordSet_odbtp {
|
---|
695 |
|
---|
696 | var $databaseType = 'odbtp_mssql';
|
---|
697 |
|
---|
698 | function ADORecordSet_odbtp_mssql($id,$mode=false)
|
---|
699 | {
|
---|
700 | return $this->ADORecordSet_odbtp($id,$mode);
|
---|
701 | }
|
---|
702 | }
|
---|
703 |
|
---|
704 | class ADORecordSet_odbtp_access extends ADORecordSet_odbtp {
|
---|
705 |
|
---|
706 | var $databaseType = 'odbtp_access';
|
---|
707 |
|
---|
708 | function ADORecordSet_odbtp_access($id,$mode=false)
|
---|
709 | {
|
---|
710 | return $this->ADORecordSet_odbtp($id,$mode);
|
---|
711 | }
|
---|
712 | }
|
---|
713 |
|
---|
714 | class ADORecordSet_odbtp_vfp extends ADORecordSet_odbtp {
|
---|
715 |
|
---|
716 | var $databaseType = 'odbtp_vfp';
|
---|
717 |
|
---|
718 | function ADORecordSet_odbtp_vfp($id,$mode=false)
|
---|
719 | {
|
---|
720 | return $this->ADORecordSet_odbtp($id,$mode);
|
---|
721 | }
|
---|
722 | }
|
---|
723 |
|
---|
724 | class ADORecordSet_odbtp_oci8 extends ADORecordSet_odbtp {
|
---|
725 |
|
---|
726 | var $databaseType = 'odbtp_oci8';
|
---|
727 |
|
---|
728 | function ADORecordSet_odbtp_oci8($id,$mode=false)
|
---|
729 | {
|
---|
730 | return $this->ADORecordSet_odbtp($id,$mode);
|
---|
731 | }
|
---|
732 | }
|
---|
733 |
|
---|
734 | class ADORecordSet_odbtp_sybase extends ADORecordSet_odbtp {
|
---|
735 |
|
---|
736 | var $databaseType = 'odbtp_sybase';
|
---|
737 |
|
---|
738 | function ADORecordSet_odbtp_sybase($id,$mode=false)
|
---|
739 | {
|
---|
740 | return $this->ADORecordSet_odbtp($id,$mode);
|
---|
741 | }
|
---|
742 | }
|
---|
743 | ?>
|
---|