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.
|
---|
7 |
|
---|
8 | Latest version is available at http://adodb.sourceforge.net
|
---|
9 |
|
---|
10 | Interbase data driver. Requires interbase client. Works on Windows and Unix.
|
---|
11 |
|
---|
12 | 3 Jan 2002 -- suggestions by Hans-Peter Oeri <kampfcaspar75@oeri.ch>
|
---|
13 | changed transaction handling and added experimental blob stuff
|
---|
14 |
|
---|
15 | Docs to interbase at the website
|
---|
16 | http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html
|
---|
17 |
|
---|
18 | To use gen_id(), see
|
---|
19 | http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen
|
---|
20 |
|
---|
21 | $rs = $conn->Execute('select gen_id(adodb,1) from rdb$database');
|
---|
22 | $id = $rs->fields[0];
|
---|
23 | $conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)");
|
---|
24 | */
|
---|
25 |
|
---|
26 | // security - hide paths
|
---|
27 | if (!defined('ADODB_DIR')) die();
|
---|
28 |
|
---|
29 | class ADODB_ibase extends ADOConnection {
|
---|
30 | var $databaseType = "ibase";
|
---|
31 | var $dataProvider = "ibase";
|
---|
32 | var $replaceQuote = "''"; // string to use to replace quotes
|
---|
33 | var $ibase_datefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';
|
---|
34 | var $fmtDate = "'Y-m-d'";
|
---|
35 | var $ibase_timestampfmt = "%Y-%m-%d %H:%M:%S";
|
---|
36 | var $ibase_timefmt = "%H:%M:%S";
|
---|
37 | var $fmtTimeStamp = "'Y-m-d, H:i:s'";
|
---|
38 | var $concat_operator='||';
|
---|
39 | var $_transactionID;
|
---|
40 | var $metaTablesSQL = "select rdb\$relation_name from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
|
---|
41 | //OPN STUFF start
|
---|
42 | var $metaColumnsSQL = "select a.rdb\$field_name, a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
|
---|
43 | //OPN STUFF end
|
---|
44 | var $ibasetrans;
|
---|
45 | var $hasGenID = true;
|
---|
46 | var $_bindInputArray = true;
|
---|
47 | var $buffers = 0;
|
---|
48 | var $dialect = 1;
|
---|
49 | var $sysDate = "cast('TODAY' as timestamp)";
|
---|
50 | var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
|
---|
51 | var $ansiOuter = true;
|
---|
52 | var $hasAffectedRows = false;
|
---|
53 | var $poorAffectedRows = true;
|
---|
54 | var $blobEncodeType = 'C';
|
---|
55 | var $role = false;
|
---|
56 |
|
---|
57 | function ADODB_ibase()
|
---|
58 | {
|
---|
59 | if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
|
---|
60 | }
|
---|
61 |
|
---|
62 |
|
---|
63 | // returns true or false
|
---|
64 | function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
|
---|
65 | {
|
---|
66 | if (!function_exists('ibase_pconnect')) return null;
|
---|
67 | if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
|
---|
68 | $fn = ($persist) ? 'ibase_pconnect':'ibase_connect';
|
---|
69 | if ($this->role)
|
---|
70 | $this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
|
---|
71 | $this->charSet,$this->buffers,$this->dialect,$this->role);
|
---|
72 | else
|
---|
73 | $this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
|
---|
74 | $this->charSet,$this->buffers,$this->dialect);
|
---|
75 |
|
---|
76 | if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
|
---|
77 | $this->replaceQuote = "''";
|
---|
78 | }
|
---|
79 | if ($this->_connectionID === false) {
|
---|
80 | $this->_handleerror();
|
---|
81 | return false;
|
---|
82 | }
|
---|
83 |
|
---|
84 | // PHP5 change.
|
---|
85 | if (function_exists('ibase_timefmt')) {
|
---|
86 | ibase_timefmt($this->ibase_datefmt,IBASE_DATE );
|
---|
87 | if ($this->dialect == 1) ibase_timefmt($this->ibase_datefmt,IBASE_TIMESTAMP );
|
---|
88 | else ibase_timefmt($this->ibase_timestampfmt,IBASE_TIMESTAMP );
|
---|
89 | ibase_timefmt($this->ibase_timefmt,IBASE_TIME );
|
---|
90 |
|
---|
91 | } else {
|
---|
92 | ini_set("ibase.timestampformat", $this->ibase_timestampfmt);
|
---|
93 | ini_set("ibase.dateformat", $this->ibase_datefmt);
|
---|
94 | ini_set("ibase.timeformat", $this->ibase_timefmt);
|
---|
95 | }
|
---|
96 | return true;
|
---|
97 | }
|
---|
98 | // returns true or false
|
---|
99 | function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
---|
100 | {
|
---|
101 | return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
|
---|
102 | }
|
---|
103 |
|
---|
104 |
|
---|
105 | function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
|
---|
106 | {
|
---|
107 | if ($internalKey) return array('RDB$DB_KEY');
|
---|
108 |
|
---|
109 | $table = strtoupper($table);
|
---|
110 |
|
---|
111 | $sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
|
---|
112 | FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
|
---|
113 | WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
|
---|
114 | ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
|
---|
115 |
|
---|
116 | $a = $this->GetCol($sql,false,true);
|
---|
117 | if ($a && sizeof($a)>0) return $a;
|
---|
118 | return false;
|
---|
119 | }
|
---|
120 |
|
---|
121 | function ServerInfo()
|
---|
122 | {
|
---|
123 | $arr['dialect'] = $this->dialect;
|
---|
124 | switch($arr['dialect']) {
|
---|
125 | case '':
|
---|
126 | case '1': $s = 'Interbase 5.5 or earlier'; break;
|
---|
127 | case '2': $s = 'Interbase 5.6'; break;
|
---|
128 | default:
|
---|
129 | case '3': $s = 'Interbase 6.0'; break;
|
---|
130 | }
|
---|
131 | $arr['version'] = ADOConnection::_findvers($s);
|
---|
132 | $arr['description'] = $s;
|
---|
133 | return $arr;
|
---|
134 | }
|
---|
135 |
|
---|
136 | function BeginTrans()
|
---|
137 | {
|
---|
138 | if ($this->transOff) return true;
|
---|
139 | $this->transCnt += 1;
|
---|
140 | $this->autoCommit = false;
|
---|
141 | $this->_transactionID = $this->_connectionID;//ibase_trans($this->ibasetrans, $this->_connectionID);
|
---|
142 | return $this->_transactionID;
|
---|
143 | }
|
---|
144 |
|
---|
145 | function CommitTrans($ok=true)
|
---|
146 | {
|
---|
147 | if (!$ok) return $this->RollbackTrans();
|
---|
148 | if ($this->transOff) return true;
|
---|
149 | if ($this->transCnt) $this->transCnt -= 1;
|
---|
150 | $ret = false;
|
---|
151 | $this->autoCommit = true;
|
---|
152 | if ($this->_transactionID) {
|
---|
153 | //print ' commit ';
|
---|
154 | $ret = ibase_commit($this->_transactionID);
|
---|
155 | }
|
---|
156 | $this->_transactionID = false;
|
---|
157 | return $ret;
|
---|
158 | }
|
---|
159 |
|
---|
160 | // there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
|
---|
161 | // it appears that ibase extension cannot support multiple concurrent queryid's
|
---|
162 | function &_Execute($sql,$inputarr=false)
|
---|
163 | {
|
---|
164 | global $ADODB_COUNTRECS;
|
---|
165 |
|
---|
166 | if ($this->_logsql) {
|
---|
167 | $savecrecs = $ADODB_COUNTRECS;
|
---|
168 | $ADODB_COUNTRECS = true; // force countrecs
|
---|
169 | $ret =& ADOConnection::_Execute($sql,$inputarr);
|
---|
170 | $ADODB_COUNTRECS = $savecrecs;
|
---|
171 | } else {
|
---|
172 | $ret =& ADOConnection::_Execute($sql,$inputarr);
|
---|
173 | }
|
---|
174 | return $ret;
|
---|
175 | }
|
---|
176 |
|
---|
177 | function RollbackTrans()
|
---|
178 | {
|
---|
179 | if ($this->transOff) return true;
|
---|
180 | if ($this->transCnt) $this->transCnt -= 1;
|
---|
181 | $ret = false;
|
---|
182 | $this->autoCommit = true;
|
---|
183 | if ($this->_transactionID)
|
---|
184 | $ret = ibase_rollback($this->_transactionID);
|
---|
185 | $this->_transactionID = false;
|
---|
186 |
|
---|
187 | return $ret;
|
---|
188 | }
|
---|
189 |
|
---|
190 | function &MetaIndexes ($table, $primary = FALSE, $owner=false)
|
---|
191 | {
|
---|
192 | // save old fetch mode
|
---|
193 | global $ADODB_FETCH_MODE;
|
---|
194 | $false = false;
|
---|
195 | $save = $ADODB_FETCH_MODE;
|
---|
196 | $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
---|
197 | if ($this->fetchMode !== FALSE) {
|
---|
198 | $savem = $this->SetFetchMode(FALSE);
|
---|
199 | }
|
---|
200 | $table = strtoupper($table);
|
---|
201 | $sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
|
---|
202 | if (!$primary) {
|
---|
203 | $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
|
---|
204 | } else {
|
---|
205 | $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
|
---|
206 | }
|
---|
207 | // get index details
|
---|
208 | $rs = $this->Execute($sql);
|
---|
209 | if (!is_object($rs)) {
|
---|
210 | // restore fetchmode
|
---|
211 | if (isset($savem)) {
|
---|
212 | $this->SetFetchMode($savem);
|
---|
213 | }
|
---|
214 | $ADODB_FETCH_MODE = $save;
|
---|
215 | return $false;
|
---|
216 | }
|
---|
217 |
|
---|
218 | $indexes = array();
|
---|
219 | while ($row = $rs->FetchRow()) {
|
---|
220 | $index = $row[0];
|
---|
221 | if (!isset($indexes[$index])) {
|
---|
222 | if (is_null($row[3])) {$row[3] = 0;}
|
---|
223 | $indexes[$index] = array(
|
---|
224 | 'unique' => ($row[3] == 1),
|
---|
225 | 'columns' => array()
|
---|
226 | );
|
---|
227 | }
|
---|
228 | $sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$index."' ORDER BY RDB\$FIELD_POSITION ASC";
|
---|
229 | $rs1 = $this->Execute($sql);
|
---|
230 | while ($row1 = $rs1->FetchRow()) {
|
---|
231 | $indexes[$index]['columns'][$row1[2]] = $row1[1];
|
---|
232 | }
|
---|
233 | }
|
---|
234 | // restore fetchmode
|
---|
235 | if (isset($savem)) {
|
---|
236 | $this->SetFetchMode($savem);
|
---|
237 | }
|
---|
238 | $ADODB_FETCH_MODE = $save;
|
---|
239 |
|
---|
240 | return $indexes;
|
---|
241 | }
|
---|
242 |
|
---|
243 |
|
---|
244 | // See http://community.borland.com/article/0,1410,25844,00.html
|
---|
245 | function RowLock($tables,$where,$col)
|
---|
246 | {
|
---|
247 | if ($this->autoCommit) $this->BeginTrans();
|
---|
248 | $this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
|
---|
249 | return 1;
|
---|
250 | }
|
---|
251 |
|
---|
252 |
|
---|
253 | function CreateSequence($seqname,$startID=1)
|
---|
254 | {
|
---|
255 | $ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
|
---|
256 | if (!$ok) return false;
|
---|
257 | return $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
|
---|
258 | }
|
---|
259 |
|
---|
260 | function DropSequence($seqname)
|
---|
261 | {
|
---|
262 | $seqname = strtoupper($seqname);
|
---|
263 | $this->Execute("delete from RDB\$GENERATORS where RDB\$GENERATOR_NAME='$seqname'");
|
---|
264 | }
|
---|
265 |
|
---|
266 | function GenID($seqname='adodbseq',$startID=1)
|
---|
267 | {
|
---|
268 | $getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
|
---|
269 | $rs = @$this->Execute($getnext);
|
---|
270 | if (!$rs) {
|
---|
271 | $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
|
---|
272 | $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
|
---|
273 | $rs = $this->Execute($getnext);
|
---|
274 | }
|
---|
275 | if ($rs && !$rs->EOF) $this->genID = (integer) reset($rs->fields);
|
---|
276 | else $this->genID = 0; // false
|
---|
277 |
|
---|
278 | if ($rs) $rs->Close();
|
---|
279 |
|
---|
280 | return $this->genID;
|
---|
281 | }
|
---|
282 |
|
---|
283 | function SelectDB($dbName)
|
---|
284 | {
|
---|
285 | return false;
|
---|
286 | }
|
---|
287 |
|
---|
288 | function _handleerror()
|
---|
289 | {
|
---|
290 | $this->_errorMsg = ibase_errmsg();
|
---|
291 | }
|
---|
292 |
|
---|
293 | function ErrorNo()
|
---|
294 | {
|
---|
295 | if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];
|
---|
296 | else return 0;
|
---|
297 | }
|
---|
298 |
|
---|
299 | function ErrorMsg()
|
---|
300 | {
|
---|
301 | return $this->_errorMsg;
|
---|
302 | }
|
---|
303 |
|
---|
304 | function Prepare($sql)
|
---|
305 | {
|
---|
306 | $stmt = ibase_prepare($this->_connectionID,$sql);
|
---|
307 | if (!$stmt) return false;
|
---|
308 | return array($sql,$stmt);
|
---|
309 | }
|
---|
310 |
|
---|
311 | // returns query ID if successful, otherwise false
|
---|
312 | // there have been reports of problems with nested queries - the code is probably not re-entrant?
|
---|
313 | function _query($sql,$iarr=false)
|
---|
314 | {
|
---|
315 |
|
---|
316 | if (!$this->autoCommit && $this->_transactionID) {
|
---|
317 | $conn = $this->_transactionID;
|
---|
318 | $docommit = false;
|
---|
319 | } else {
|
---|
320 | $conn = $this->_connectionID;
|
---|
321 | $docommit = true;
|
---|
322 | }
|
---|
323 | if (is_array($sql)) {
|
---|
324 | $fn = 'ibase_execute';
|
---|
325 | $sql = $sql[1];
|
---|
326 | if (is_array($iarr)) {
|
---|
327 | if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
|
---|
328 | if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
|
---|
329 | $fnarr =& array_merge( array($sql) , $iarr);
|
---|
330 | $ret = call_user_func_array($fn,$fnarr);
|
---|
331 | } else {
|
---|
332 | switch(sizeof($iarr)) {
|
---|
333 | case 1: $ret = $fn($sql,$iarr[0]); break;
|
---|
334 | case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;
|
---|
335 | case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
|
---|
336 | case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
|
---|
337 | case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
|
---|
338 | case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
|
---|
339 | case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
|
---|
340 | default: ADOConnection::outp( "Too many parameters to ibase query $sql");
|
---|
341 | case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
|
---|
342 | }
|
---|
343 | }
|
---|
344 | } else $ret = $fn($sql);
|
---|
345 | } else {
|
---|
346 | $fn = 'ibase_query';
|
---|
347 |
|
---|
348 | if (is_array($iarr)) {
|
---|
349 | if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
|
---|
350 | if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
|
---|
351 | $fnarr =& array_merge( array($conn,$sql) , $iarr);
|
---|
352 | $ret = call_user_func_array($fn,$fnarr);
|
---|
353 | } else {
|
---|
354 | switch(sizeof($iarr)) {
|
---|
355 | case 1: $ret = $fn($conn,$sql,$iarr[0]); break;
|
---|
356 | case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;
|
---|
357 | case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
|
---|
358 | case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
|
---|
359 | case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
|
---|
360 | case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
|
---|
361 | case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
|
---|
362 | default: ADOConnection::outp( "Too many parameters to ibase query $sql");
|
---|
363 | case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
|
---|
364 | }
|
---|
365 | }
|
---|
366 | } else $ret = $fn($conn,$sql);
|
---|
367 | }
|
---|
368 | if ($docommit && $ret === true) ibase_commit($this->_connectionID);
|
---|
369 |
|
---|
370 | $this->_handleerror();
|
---|
371 | return $ret;
|
---|
372 | }
|
---|
373 |
|
---|
374 | // returns true or false
|
---|
375 | function _close()
|
---|
376 | {
|
---|
377 | if (!$this->autoCommit) @ibase_rollback($this->_connectionID);
|
---|
378 | return @ibase_close($this->_connectionID);
|
---|
379 | }
|
---|
380 |
|
---|
381 | //OPN STUFF start
|
---|
382 | function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
|
---|
383 | {
|
---|
384 | $fscale = abs($fscale);
|
---|
385 | $fld->max_length = $flen;
|
---|
386 | $fld->scale = null;
|
---|
387 | switch($ftype){
|
---|
388 | case 7:
|
---|
389 | case 8:
|
---|
390 | if ($dialect3) {
|
---|
391 | switch($fsubtype){
|
---|
392 | case 0:
|
---|
393 | $fld->type = ($ftype == 7 ? 'smallint' : 'integer');
|
---|
394 | break;
|
---|
395 | case 1:
|
---|
396 | $fld->type = 'numeric';
|
---|
397 | $fld->max_length = $fprecision;
|
---|
398 | $fld->scale = $fscale;
|
---|
399 | break;
|
---|
400 | case 2:
|
---|
401 | $fld->type = 'decimal';
|
---|
402 | $fld->max_length = $fprecision;
|
---|
403 | $fld->scale = $fscale;
|
---|
404 | break;
|
---|
405 | } // switch
|
---|
406 | } else {
|
---|
407 | if ($fscale !=0) {
|
---|
408 | $fld->type = 'decimal';
|
---|
409 | $fld->scale = $fscale;
|
---|
410 | $fld->max_length = ($ftype == 7 ? 4 : 9);
|
---|
411 | } else {
|
---|
412 | $fld->type = ($ftype == 7 ? 'smallint' : 'integer');
|
---|
413 | }
|
---|
414 | }
|
---|
415 | break;
|
---|
416 | case 16:
|
---|
417 | if ($dialect3) {
|
---|
418 | switch($fsubtype){
|
---|
419 | case 0:
|
---|
420 | $fld->type = 'decimal';
|
---|
421 | $fld->max_length = 18;
|
---|
422 | $fld->scale = 0;
|
---|
423 | break;
|
---|
424 | case 1:
|
---|
425 | $fld->type = 'numeric';
|
---|
426 | $fld->max_length = $fprecision;
|
---|
427 | $fld->scale = $fscale;
|
---|
428 | break;
|
---|
429 | case 2:
|
---|
430 | $fld->type = 'decimal';
|
---|
431 | $fld->max_length = $fprecision;
|
---|
432 | $fld->scale = $fscale;
|
---|
433 | break;
|
---|
434 | } // switch
|
---|
435 | }
|
---|
436 | break;
|
---|
437 | case 10:
|
---|
438 | $fld->type = 'float';
|
---|
439 | break;
|
---|
440 | case 14:
|
---|
441 | $fld->type = 'char';
|
---|
442 | break;
|
---|
443 | case 27:
|
---|
444 | if ($fscale !=0) {
|
---|
445 | $fld->type = 'decimal';
|
---|
446 | $fld->max_length = 15;
|
---|
447 | $fld->scale = 5;
|
---|
448 | } else {
|
---|
449 | $fld->type = 'double';
|
---|
450 | }
|
---|
451 | break;
|
---|
452 | case 35:
|
---|
453 | if ($dialect3) {
|
---|
454 | $fld->type = 'timestamp';
|
---|
455 | } else {
|
---|
456 | $fld->type = 'date';
|
---|
457 | }
|
---|
458 | break;
|
---|
459 | case 12:
|
---|
460 | $fld->type = 'date';
|
---|
461 | break;
|
---|
462 | case 13:
|
---|
463 | $fld->type = 'time';
|
---|
464 | break;
|
---|
465 | case 37:
|
---|
466 | $fld->type = 'varchar';
|
---|
467 | break;
|
---|
468 | case 40:
|
---|
469 | $fld->type = 'cstring';
|
---|
470 | break;
|
---|
471 | case 261:
|
---|
472 | $fld->type = 'blob';
|
---|
473 | $fld->max_length = -1;
|
---|
474 | break;
|
---|
475 | } // switch
|
---|
476 | }
|
---|
477 | //OPN STUFF end
|
---|
478 | // returns array of ADOFieldObjects for current table
|
---|
479 | function &MetaColumns($table)
|
---|
480 | {
|
---|
481 | global $ADODB_FETCH_MODE;
|
---|
482 |
|
---|
483 | $save = $ADODB_FETCH_MODE;
|
---|
484 | $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
---|
485 |
|
---|
486 | $rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
|
---|
487 |
|
---|
488 | $ADODB_FETCH_MODE = $save;
|
---|
489 | $false = false;
|
---|
490 | if ($rs === false) {
|
---|
491 | return $false;
|
---|
492 | }
|
---|
493 |
|
---|
494 | $retarr = array();
|
---|
495 | //OPN STUFF start
|
---|
496 | $dialect3 = ($this->dialect==3 ? true : false);
|
---|
497 | //OPN STUFF end
|
---|
498 | while (!$rs->EOF) { //print_r($rs->fields);
|
---|
499 | $fld = new ADOFieldObject();
|
---|
500 | $fld->name = trim($rs->fields[0]);
|
---|
501 | //OPN STUFF start
|
---|
502 | $this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
|
---|
503 | if (isset($rs->fields[1]) && $rs->fields[1]) {
|
---|
504 | $fld->not_null = true;
|
---|
505 | }
|
---|
506 | if (isset($rs->fields[2])) {
|
---|
507 |
|
---|
508 | $fld->has_default = true;
|
---|
509 | $d = substr($rs->fields[2],strlen('default '));
|
---|
510 | switch ($fld->type)
|
---|
511 | {
|
---|
512 | case 'smallint':
|
---|
513 | case 'integer': $fld->default_value = (int) $d; break;
|
---|
514 | case 'char':
|
---|
515 | case 'blob':
|
---|
516 | case 'text':
|
---|
517 | case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
|
---|
518 | case 'double':
|
---|
519 | case 'float': $fld->default_value = (float) $d; break;
|
---|
520 | default: $fld->default_value = $d; break;
|
---|
521 | }
|
---|
522 | // case 35:$tt = 'TIMESTAMP'; break;
|
---|
523 | }
|
---|
524 | if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
|
---|
525 | $fld->sub_type = $rs->fields[5];
|
---|
526 | } else {
|
---|
527 | $fld->sub_type = null;
|
---|
528 | }
|
---|
529 | //OPN STUFF end
|
---|
530 | if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
---|
531 | else $retarr[strtoupper($fld->name)] = $fld;
|
---|
532 |
|
---|
533 | $rs->MoveNext();
|
---|
534 | }
|
---|
535 | $rs->Close();
|
---|
536 | if ( empty($retarr)) return $false;
|
---|
537 | else return $retarr;
|
---|
538 | }
|
---|
539 |
|
---|
540 | function BlobEncode( $blob )
|
---|
541 | {
|
---|
542 | $blobid = ibase_blob_create( $this->_connectionID);
|
---|
543 | ibase_blob_add( $blobid, $blob );
|
---|
544 | return ibase_blob_close( $blobid );
|
---|
545 | }
|
---|
546 |
|
---|
547 | // since we auto-decode all blob's since 2.42,
|
---|
548 | // BlobDecode should not do any transforms
|
---|
549 | function BlobDecode($blob)
|
---|
550 | {
|
---|
551 | return $blob;
|
---|
552 | }
|
---|
553 |
|
---|
554 |
|
---|
555 |
|
---|
556 |
|
---|
557 | // old blobdecode function
|
---|
558 | // still used to auto-decode all blob's
|
---|
559 | function _BlobDecode_old( $blob )
|
---|
560 | {
|
---|
561 | $blobid = ibase_blob_open($this->_connectionID, $blob );
|
---|
562 | $realblob = ibase_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>
|
---|
563 | while($string = ibase_blob_get($blobid, 8192)){
|
---|
564 | $realblob .= $string;
|
---|
565 | }
|
---|
566 | ibase_blob_close( $blobid );
|
---|
567 |
|
---|
568 | return( $realblob );
|
---|
569 | }
|
---|
570 |
|
---|
571 | function _BlobDecode( $blob )
|
---|
572 | {
|
---|
573 | if (ADODB_PHPVER >= 0x5000) {
|
---|
574 | $blob_data = ibase_blob_info($this->_connectionID, $blob );
|
---|
575 | $blobid = ibase_blob_open($this->_connectionID, $blob );
|
---|
576 | } else {
|
---|
577 |
|
---|
578 | $blob_data = ibase_blob_info( $blob );
|
---|
579 | $blobid = ibase_blob_open( $blob );
|
---|
580 | }
|
---|
581 |
|
---|
582 | if( $blob_data[0] > $this->maxblobsize ) {
|
---|
583 |
|
---|
584 | $realblob = ibase_blob_get($blobid, $this->maxblobsize);
|
---|
585 |
|
---|
586 | while($string = ibase_blob_get($blobid, 8192)){
|
---|
587 | $realblob .= $string;
|
---|
588 | }
|
---|
589 | } else {
|
---|
590 | $realblob = ibase_blob_get($blobid, $blob_data[0]);
|
---|
591 | }
|
---|
592 |
|
---|
593 | ibase_blob_close( $blobid );
|
---|
594 | return( $realblob );
|
---|
595 | }
|
---|
596 |
|
---|
597 | function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
|
---|
598 | {
|
---|
599 | $fd = fopen($path,'rb');
|
---|
600 | if ($fd === false) return false;
|
---|
601 | $blob_id = ibase_blob_create($this->_connectionID);
|
---|
602 |
|
---|
603 | /* fill with data */
|
---|
604 |
|
---|
605 | while ($val = fread($fd,32768)){
|
---|
606 | ibase_blob_add($blob_id, $val);
|
---|
607 | }
|
---|
608 |
|
---|
609 | /* close and get $blob_id_str for inserting into table */
|
---|
610 | $blob_id_str = ibase_blob_close($blob_id);
|
---|
611 |
|
---|
612 | fclose($fd);
|
---|
613 | return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
|
---|
614 | }
|
---|
615 |
|
---|
616 | /*
|
---|
617 | Insert a null into the blob field of the table first.
|
---|
618 | Then use UpdateBlob to store the blob.
|
---|
619 |
|
---|
620 | Usage:
|
---|
621 |
|
---|
622 | $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
|
---|
623 | $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
|
---|
624 | */
|
---|
625 | function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
---|
626 | {
|
---|
627 | $blob_id = ibase_blob_create($this->_connectionID);
|
---|
628 |
|
---|
629 | // ibase_blob_add($blob_id, $val);
|
---|
630 |
|
---|
631 | // replacement that solves the problem by which only the first modulus 64K /
|
---|
632 | // of $val are stored at the blob field ////////////////////////////////////
|
---|
633 | // Thx Abel Berenstein aberenstein#afip.gov.ar
|
---|
634 | $len = strlen($val);
|
---|
635 | $chunk_size = 32768;
|
---|
636 | $tail_size = $len % $chunk_size;
|
---|
637 | $n_chunks = ($len - $tail_size) / $chunk_size;
|
---|
638 |
|
---|
639 | for ($n = 0; $n < $n_chunks; $n++) {
|
---|
640 | $start = $n * $chunk_size;
|
---|
641 | $data = substr($val, $start, $chunk_size);
|
---|
642 | ibase_blob_add($blob_id, $data);
|
---|
643 | }
|
---|
644 |
|
---|
645 | if ($tail_size) {
|
---|
646 | $start = $n_chunks * $chunk_size;
|
---|
647 | $data = substr($val, $start, $tail_size);
|
---|
648 | ibase_blob_add($blob_id, $data);
|
---|
649 | }
|
---|
650 | // end replacement /////////////////////////////////////////////////////////
|
---|
651 |
|
---|
652 | $blob_id_str = ibase_blob_close($blob_id);
|
---|
653 |
|
---|
654 | return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
|
---|
655 |
|
---|
656 | }
|
---|
657 |
|
---|
658 |
|
---|
659 | function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
---|
660 | {
|
---|
661 | $blob_id = ibase_blob_create($this->_connectionID);
|
---|
662 | ibase_blob_add($blob_id, $val);
|
---|
663 | $blob_id_str = ibase_blob_close($blob_id);
|
---|
664 | return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
|
---|
665 | }
|
---|
666 |
|
---|
667 | // Format date column in sql string given an input format that understands Y M D
|
---|
668 | // Only since Interbase 6.0 - uses EXTRACT
|
---|
669 | // problem - does not zero-fill the day and month yet
|
---|
670 | function SQLDate($fmt, $col=false)
|
---|
671 | {
|
---|
672 | if (!$col) $col = $this->sysDate;
|
---|
673 | $s = '';
|
---|
674 |
|
---|
675 | $len = strlen($fmt);
|
---|
676 | for ($i=0; $i < $len; $i++) {
|
---|
677 | if ($s) $s .= '||';
|
---|
678 | $ch = $fmt[$i];
|
---|
679 | switch($ch) {
|
---|
680 | case 'Y':
|
---|
681 | case 'y':
|
---|
682 | $s .= "extract(year from $col)";
|
---|
683 | break;
|
---|
684 | case 'M':
|
---|
685 | case 'm':
|
---|
686 | $s .= "extract(month from $col)";
|
---|
687 | break;
|
---|
688 | case 'Q':
|
---|
689 | case 'q':
|
---|
690 | $s .= "cast(((extract(month from $col)+2) / 3) as integer)";
|
---|
691 | break;
|
---|
692 | case 'D':
|
---|
693 | case 'd':
|
---|
694 | $s .= "(extract(day from $col))";
|
---|
695 | break;
|
---|
696 | case 'H':
|
---|
697 | case 'h':
|
---|
698 | $s .= "(extract(hour from $col))";
|
---|
699 | break;
|
---|
700 | case 'I':
|
---|
701 | case 'i':
|
---|
702 | $s .= "(extract(minute from $col))";
|
---|
703 | break;
|
---|
704 | case 'S':
|
---|
705 | case 's':
|
---|
706 | $s .= "CAST((extract(second from $col)) AS INTEGER)";
|
---|
707 | break;
|
---|
708 |
|
---|
709 | default:
|
---|
710 | if ($ch == '\\') {
|
---|
711 | $i++;
|
---|
712 | $ch = substr($fmt,$i,1);
|
---|
713 | }
|
---|
714 | $s .= $this->qstr($ch);
|
---|
715 | break;
|
---|
716 | }
|
---|
717 | }
|
---|
718 | return $s;
|
---|
719 | }
|
---|
720 | }
|
---|
721 |
|
---|
722 | /*--------------------------------------------------------------------------------------
|
---|
723 | Class Name: Recordset
|
---|
724 | --------------------------------------------------------------------------------------*/
|
---|
725 |
|
---|
726 | class ADORecordset_ibase extends ADORecordSet
|
---|
727 | {
|
---|
728 |
|
---|
729 | var $databaseType = "ibase";
|
---|
730 | var $bind=false;
|
---|
731 | var $_cacheType;
|
---|
732 |
|
---|
733 | function ADORecordset_ibase($id,$mode=false)
|
---|
734 | {
|
---|
735 | global $ADODB_FETCH_MODE;
|
---|
736 |
|
---|
737 | $this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
|
---|
738 | $this->ADORecordSet($id);
|
---|
739 | }
|
---|
740 |
|
---|
741 | /* Returns: an object containing field information.
|
---|
742 | Get column information in the Recordset object. fetchField() can be used in order to obtain information about
|
---|
743 | fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
|
---|
744 | fetchField() is retrieved. */
|
---|
745 |
|
---|
746 | function &FetchField($fieldOffset = -1)
|
---|
747 | {
|
---|
748 | $fld = new ADOFieldObject;
|
---|
749 | $ibf = ibase_field_info($this->_queryID,$fieldOffset);
|
---|
750 | switch (ADODB_ASSOC_CASE) {
|
---|
751 | case 2: // the default
|
---|
752 | $fld->name = ($ibf['alias']);
|
---|
753 | if (empty($fld->name)) $fld->name = ($ibf['name']);
|
---|
754 | break;
|
---|
755 | case 0:
|
---|
756 | $fld->name = strtoupper($ibf['alias']);
|
---|
757 | if (empty($fld->name)) $fld->name = strtoupper($ibf['name']);
|
---|
758 | break;
|
---|
759 | case 1:
|
---|
760 | $fld->name = strtolower($ibf['alias']);
|
---|
761 | if (empty($fld->name)) $fld->name = strtolower($ibf['name']);
|
---|
762 | break;
|
---|
763 | }
|
---|
764 |
|
---|
765 | $fld->type = $ibf['type'];
|
---|
766 | $fld->max_length = $ibf['length'];
|
---|
767 |
|
---|
768 | /* This needs to be populated from the metadata */
|
---|
769 | $fld->not_null = false;
|
---|
770 | $fld->has_default = false;
|
---|
771 | $fld->default_value = 'null';
|
---|
772 | return $fld;
|
---|
773 | }
|
---|
774 |
|
---|
775 | function _initrs()
|
---|
776 | {
|
---|
777 | $this->_numOfRows = -1;
|
---|
778 | $this->_numOfFields = @ibase_num_fields($this->_queryID);
|
---|
779 |
|
---|
780 | // cache types for blob decode check
|
---|
781 | for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
|
---|
782 | $f1 = $this->FetchField($i);
|
---|
783 | $this->_cacheType[] = $f1->type;
|
---|
784 | }
|
---|
785 | }
|
---|
786 |
|
---|
787 | function _seek($row)
|
---|
788 | {
|
---|
789 | return false;
|
---|
790 | }
|
---|
791 |
|
---|
792 | function _fetch()
|
---|
793 | {
|
---|
794 | $f = @ibase_fetch_row($this->_queryID);
|
---|
795 | if ($f === false) {
|
---|
796 | $this->fields = false;
|
---|
797 | return false;
|
---|
798 | }
|
---|
799 | // OPN stuff start - optimized
|
---|
800 | // fix missing nulls and decode blobs automatically
|
---|
801 |
|
---|
802 | global $ADODB_ANSI_PADDING_OFF;
|
---|
803 | //$ADODB_ANSI_PADDING_OFF=1;
|
---|
804 | $rtrim = !empty($ADODB_ANSI_PADDING_OFF);
|
---|
805 |
|
---|
806 | for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
|
---|
807 | if ($this->_cacheType[$i]=="BLOB") {
|
---|
808 | if (isset($f[$i])) {
|
---|
809 | $f[$i] = $this->connection->_BlobDecode($f[$i]);
|
---|
810 | } else {
|
---|
811 | $f[$i] = null;
|
---|
812 | }
|
---|
813 | } else {
|
---|
814 | if (!isset($f[$i])) {
|
---|
815 | $f[$i] = null;
|
---|
816 | } else if ($rtrim && is_string($f[$i])) {
|
---|
817 | $f[$i] = rtrim($f[$i]);
|
---|
818 | }
|
---|
819 | }
|
---|
820 | }
|
---|
821 | // OPN stuff end
|
---|
822 |
|
---|
823 | $this->fields = $f;
|
---|
824 | if ($this->fetchMode == ADODB_FETCH_ASSOC) {
|
---|
825 | $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
|
---|
826 | } else if ($this->fetchMode == ADODB_FETCH_BOTH) {
|
---|
827 | $this->fields =& array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
|
---|
828 | }
|
---|
829 | return true;
|
---|
830 | }
|
---|
831 |
|
---|
832 | /* Use associative array to get fields array */
|
---|
833 | function Fields($colname)
|
---|
834 | {
|
---|
835 | if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
|
---|
836 | if (!$this->bind) {
|
---|
837 | $this->bind = array();
|
---|
838 | for ($i=0; $i < $this->_numOfFields; $i++) {
|
---|
839 | $o = $this->FetchField($i);
|
---|
840 | $this->bind[strtoupper($o->name)] = $i;
|
---|
841 | }
|
---|
842 | }
|
---|
843 |
|
---|
844 | return $this->fields[$this->bind[strtoupper($colname)]];
|
---|
845 |
|
---|
846 | }
|
---|
847 |
|
---|
848 |
|
---|
849 | function _close()
|
---|
850 | {
|
---|
851 | return @ibase_free_result($this->_queryID);
|
---|
852 | }
|
---|
853 |
|
---|
854 | function MetaType($t,$len=-1,$fieldobj=false)
|
---|
855 | {
|
---|
856 | if (is_object($t)) {
|
---|
857 | $fieldobj = $t;
|
---|
858 | $t = $fieldobj->type;
|
---|
859 | $len = $fieldobj->max_length;
|
---|
860 | }
|
---|
861 | switch (strtoupper($t)) {
|
---|
862 | case 'CHAR':
|
---|
863 | return 'C';
|
---|
864 |
|
---|
865 | case 'TEXT':
|
---|
866 | case 'VARCHAR':
|
---|
867 | case 'VARYING':
|
---|
868 | if ($len <= $this->blobSize) return 'C';
|
---|
869 | return 'X';
|
---|
870 | case 'BLOB':
|
---|
871 | return 'B';
|
---|
872 |
|
---|
873 | case 'TIMESTAMP':
|
---|
874 | case 'DATE': return 'D';
|
---|
875 | case 'TIME': return 'T';
|
---|
876 | //case 'T': return 'T';
|
---|
877 |
|
---|
878 | //case 'L': return 'L';
|
---|
879 | case 'INT':
|
---|
880 | case 'SHORT':
|
---|
881 | case 'INTEGER': return 'I';
|
---|
882 | default: return 'N';
|
---|
883 | }
|
---|
884 | }
|
---|
885 |
|
---|
886 | }
|
---|
887 | ?> |
---|