PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/adodb/adodb-lib.inc.php

https://bitbucket.org/hky/bytehoard2
PHP | 899 lines | 630 code | 125 blank | 144 comment | 191 complexity | ed43a7b198e8595413747af590d62a90 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. // security - hide paths
  3. if (!defined('ADODB_DIR')) die();
  4. global $ADODB_INCLUDED_LIB;
  5. $ADODB_INCLUDED_LIB = 1;
  6. /*
  7. @version V4.61 24 Feb 2005 (c) 2000-2005 John Lim (jlim\@natsoft.com.my). All rights reserved.
  8. Released under both BSD license and Lesser GPL library license.
  9. Whenever there is any discrepancy between the two licenses,
  10. the BSD license will take precedence. See License.txt.
  11. Set tabs to 4 for best viewing.
  12. Less commonly used functions are placed here to reduce size of adodb.inc.php.
  13. */
  14. // Force key to upper.
  15. // See also http://www.php.net/manual/en/function.array-change-key-case.php
  16. function _array_change_key_case($an_array)
  17. {
  18. if (is_array($an_array)) {
  19. $new_array = array();
  20. foreach($an_array as $key=>$value)
  21. $new_array[strtoupper($key)] = $value;
  22. return $new_array;
  23. }
  24. return $an_array;
  25. }
  26. function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
  27. {
  28. if (count($fieldArray) == 0) return 0;
  29. $first = true;
  30. $uSet = '';
  31. if (!is_array($keyCol)) {
  32. $keyCol = array($keyCol);
  33. }
  34. foreach($fieldArray as $k => $v) {
  35. if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
  36. $v = $zthis->qstr($v);
  37. $fieldArray[$k] = $v;
  38. }
  39. if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
  40. if ($first) {
  41. $first = false;
  42. $uSet = "$k=$v";
  43. } else
  44. $uSet .= ",$k=$v";
  45. }
  46. $where = false;
  47. foreach ($keyCol as $v) {
  48. if ($where) $where .= " and $v=$fieldArray[$v]";
  49. else $where = "$v=$fieldArray[$v]";
  50. }
  51. if ($uSet && $where) {
  52. $update = "UPDATE $table SET $uSet WHERE $where";
  53. $rs = $zthis->Execute($update);
  54. if ($rs) {
  55. if ($zthis->poorAffectedRows) {
  56. /*
  57. The Select count(*) wipes out any errors that the update would have returned.
  58. http://phplens.com/lens/lensforum/msgs.php?id=5696
  59. */
  60. if ($zthis->ErrorNo()<>0) return 0;
  61. # affected_rows == 0 if update field values identical to old values
  62. # for mysql - which is silly.
  63. $cnt = $zthis->GetOne("select count(*) from $table where $where");
  64. if ($cnt > 0) return 1; // record already exists
  65. } else {
  66. if (($zthis->Affected_Rows()>0)) return 1;
  67. }
  68. } else
  69. return 0;
  70. }
  71. // print "<p>Error=".$this->ErrorNo().'<p>';
  72. $first = true;
  73. foreach($fieldArray as $k => $v) {
  74. if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
  75. if ($first) {
  76. $first = false;
  77. $iCols = "$k";
  78. $iVals = "$v";
  79. } else {
  80. $iCols .= ",$k";
  81. $iVals .= ",$v";
  82. }
  83. }
  84. $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
  85. $rs = $zthis->Execute($insert);
  86. return ($rs) ? 2 : 0;
  87. }
  88. // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
  89. function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
  90. $size=0, $selectAttr='',$compareFields0=true)
  91. {
  92. $hasvalue = false;
  93. if ($multiple or is_array($defstr)) {
  94. if ($size==0) $size=5;
  95. $attr = ' multiple size="'.$size.'"';
  96. if (!strpos($name,'[]')) $name .= '[]';
  97. } else if ($size) $attr = ' size="'.$size.'"';
  98. else $attr ='';
  99. $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
  100. if ($blank1stItem)
  101. if (is_string($blank1stItem)) {
  102. $barr = explode(':',$blank1stItem);
  103. if (sizeof($barr) == 1) $barr[] = '';
  104. $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
  105. } else $s .= "\n<option></option>";
  106. if ($zthis->FieldCount() > 1) $hasvalue=true;
  107. else $compareFields0 = true;
  108. $value = '';
  109. while(!$zthis->EOF) {
  110. $zval = rtrim(reset($zthis->fields));
  111. if (sizeof($zthis->fields) > 1) {
  112. if (isset($zthis->fields[1]))
  113. $zval2 = rtrim($zthis->fields[1]);
  114. else
  115. $zval2 = rtrim(next($zthis->fields));
  116. }
  117. $selected = ($compareFields0) ? $zval : $zval2;
  118. if ($blank1stItem && $zval=="") {
  119. $zthis->MoveNext();
  120. continue;
  121. }
  122. if ($hasvalue)
  123. $value = " value='".htmlspecialchars($zval2)."'";
  124. if (is_array($defstr)) {
  125. if (in_array($selected,$defstr))
  126. $s .= "<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
  127. else
  128. $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
  129. }
  130. else {
  131. if (strcasecmp($selected,$defstr)==0)
  132. $s .= "<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
  133. else
  134. $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
  135. }
  136. $zthis->MoveNext();
  137. } // while
  138. return $s ."\n</select>\n";
  139. }
  140. /*
  141. Count the number of records this sql statement will return by using
  142. query rewriting techniques...
  143. Does not work with UNIONs.
  144. */
  145. function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
  146. {
  147. $qryRecs = 0;
  148. if (preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || preg_match('/\s+GROUP\s+BY\s+/is',$sql)) {
  149. // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
  150. // but this is only supported by oracle and postgresql...
  151. if ($zthis->dataProvider == 'oci8') {
  152. $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
  153. // Allow Oracle hints to be used for query optimization, Chris Wrye
  154. if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
  155. $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
  156. } else
  157. $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
  158. } else if ( $zthis->databaseType == 'postgres' || $zthis->databaseType == 'postgres7') {
  159. $info = $zthis->ServerInfo();
  160. if (substr($info['version'],0,3) >= 7.1) { // good till version 999
  161. $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
  162. $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
  163. }
  164. }
  165. } else {
  166. // now replace SELECT ... FROM with SELECT COUNT(*) FROM
  167. $rewritesql = preg_replace(
  168. '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
  169. // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
  170. // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
  171. $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
  172. }
  173. if (isset($rewritesql) && $rewritesql != $sql) {
  174. if ($secs2cache) {
  175. // we only use half the time of secs2cache because the count can quickly
  176. // become inaccurate if new records are added
  177. $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
  178. } else {
  179. $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
  180. }
  181. if ($qryRecs !== false) return $qryRecs;
  182. }
  183. //--------------------------------------------
  184. // query rewrite failed - so try slower way...
  185. // strip off unneeded ORDER BY if no UNION
  186. if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
  187. else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
  188. $rstest = &$zthis->Execute($rewritesql,$inputarr);
  189. if ($rstest) {
  190. $qryRecs = $rstest->RecordCount();
  191. if ($qryRecs == -1) {
  192. global $ADODB_EXTENSION;
  193. // some databases will return -1 on MoveLast() - change to MoveNext()
  194. if ($ADODB_EXTENSION) {
  195. while(!$rstest->EOF) {
  196. adodb_movenext($rstest);
  197. }
  198. } else {
  199. while(!$rstest->EOF) {
  200. $rstest->MoveNext();
  201. }
  202. }
  203. $qryRecs = $rstest->_currentRow;
  204. }
  205. $rstest->Close();
  206. if ($qryRecs == -1) return 0;
  207. }
  208. return $qryRecs;
  209. }
  210. /*
  211. Code originally from "Cornel G" <conyg@fx.ro>
  212. This code will not work with SQL that has UNION in it
  213. Also if you are using CachePageExecute(), there is a strong possibility that
  214. data will get out of synch. use CachePageExecute() only with tables that
  215. rarely change.
  216. */
  217. function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
  218. $inputarr=false, $secs2cache=0)
  219. {
  220. $atfirstpage = false;
  221. $atlastpage = false;
  222. $lastpageno=1;
  223. // If an invalid nrows is supplied,
  224. // we assume a default value of 10 rows per page
  225. if (!isset($nrows) || $nrows <= 0) $nrows = 10;
  226. $qryRecs = false; //count records for no offset
  227. $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
  228. $lastpageno = (int) ceil($qryRecs / $nrows);
  229. $zthis->_maxRecordCount = $qryRecs;
  230. // ***** Here we check whether $page is the last page or
  231. // whether we are trying to retrieve
  232. // a page number greater than the last page number.
  233. if ($page >= $lastpageno) {
  234. $page = $lastpageno;
  235. $atlastpage = true;
  236. }
  237. // If page number <= 1, then we are at the first page
  238. if (empty($page) || $page <= 1) {
  239. $page = 1;
  240. $atfirstpage = true;
  241. }
  242. // We get the data we want
  243. $offset = $nrows * ($page-1);
  244. if ($secs2cache > 0)
  245. $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
  246. else
  247. $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
  248. // Before returning the RecordSet, we set the pagination properties we need
  249. if ($rsreturn) {
  250. $rsreturn->_maxRecordCount = $qryRecs;
  251. $rsreturn->rowsPerPage = $nrows;
  252. $rsreturn->AbsolutePage($page);
  253. $rsreturn->AtFirstPage($atfirstpage);
  254. $rsreturn->AtLastPage($atlastpage);
  255. $rsreturn->LastPageNo($lastpageno);
  256. }
  257. return $rsreturn;
  258. }
  259. // Iván Oliva version
  260. function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
  261. {
  262. $atfirstpage = false;
  263. $atlastpage = false;
  264. if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page
  265. $page = 1;
  266. $atfirstpage = true;
  267. }
  268. if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
  269. // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
  270. // the last page number.
  271. $pagecounter = $page + 1;
  272. $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
  273. if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
  274. else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
  275. if ($rstest) {
  276. while ($rstest && $rstest->EOF && $pagecounter>0) {
  277. $atlastpage = true;
  278. $pagecounter--;
  279. $pagecounteroffset = $nrows * ($pagecounter - 1);
  280. $rstest->Close();
  281. if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
  282. else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
  283. }
  284. if ($rstest) $rstest->Close();
  285. }
  286. if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
  287. $page = $pagecounter;
  288. if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
  289. //... page, that is, the recordset has only 1 page.
  290. }
  291. // We get the data we want
  292. $offset = $nrows * ($page-1);
  293. if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
  294. else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
  295. // Before returning the RecordSet, we set the pagination properties we need
  296. if ($rsreturn) {
  297. $rsreturn->rowsPerPage = $nrows;
  298. $rsreturn->AbsolutePage($page);
  299. $rsreturn->AtFirstPage($atfirstpage);
  300. $rsreturn->AtLastPage($atlastpage);
  301. }
  302. return $rsreturn;
  303. }
  304. function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
  305. {
  306. if (!$rs) {
  307. printf(ADODB_BAD_RS,'GetUpdateSQL');
  308. return false;
  309. }
  310. $fieldUpdatedCount = 0;
  311. $arrFields = _array_change_key_case($arrFields);
  312. $hasnumeric = isset($rs->fields[0]);
  313. $setFields = '';
  314. // Loop through all of the fields in the recordset
  315. for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
  316. // Get the field from the recordset
  317. $field = $rs->FetchField($i);
  318. // If the recordset field is one
  319. // of the fields passed in then process.
  320. $upperfname = strtoupper($field->name);
  321. if (adodb_key_exists($upperfname,$arrFields,$force)) {
  322. // If the existing field value in the recordset
  323. // is different from the value passed in then
  324. // go ahead and append the field name and new value to
  325. // the update query.
  326. if ($hasnumeric) $val = $rs->fields[$i];
  327. else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
  328. else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name];
  329. else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)];
  330. else $val = '';
  331. if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
  332. // Set the counter for the number of fields that will be updated.
  333. $fieldUpdatedCount++;
  334. // Based on the datatype of the field
  335. // Format the value properly for the database
  336. $type = $rs->MetaType($field->type);
  337. if ($type == 'null') {
  338. $type = 'C';
  339. }
  340. if (strpos($upperfname,' ') !== false)
  341. $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
  342. else
  343. $fnameq = $upperfname;
  344. // is_null requires php 4.0.4
  345. //********************************************************//
  346. if (is_null($arrFields[$upperfname])
  347. || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
  348. || $arrFields[$upperfname] === 'null'
  349. )
  350. {
  351. switch ($force) {
  352. //case 0:
  353. // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
  354. //break;
  355. case 1:
  356. //Set null
  357. $setFields .= $field->name . " = null, ";
  358. break;
  359. case 2:
  360. //Set empty
  361. $arrFields[$upperfname] = "";
  362. $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
  363. break;
  364. default:
  365. case 3:
  366. //Set the value that was given in array, so you can give both null and empty values
  367. if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') {
  368. $setFields .= $field->name . " = null, ";
  369. } else {
  370. $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
  371. }
  372. break;
  373. }
  374. //********************************************************//
  375. } else {
  376. //we do this so each driver can customize the sql for
  377. //DB specific column types.
  378. //Oracle needs BLOB types to be handled with a returning clause
  379. //postgres has special needs as well
  380. $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
  381. $arrFields, $magicq);
  382. }
  383. }
  384. }
  385. }
  386. // If there were any modified fields then build the rest of the update query.
  387. if ($fieldUpdatedCount > 0 || $forceUpdate) {
  388. // Get the table name from the existing query.
  389. preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
  390. // Get the full where clause excluding the word "WHERE" from
  391. // the existing query.
  392. preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
  393. $discard = false;
  394. // not a good hack, improvements?
  395. if ($whereClause) {
  396. if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
  397. else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
  398. else preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard);
  399. } else
  400. $whereClause = array(false,false);
  401. if ($discard)
  402. $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
  403. $sql = 'UPDATE '.$tableName[1].' SET '.substr($setFields, 0, -2);
  404. if (strlen($whereClause[1]) > 0)
  405. $sql .= ' WHERE '.$whereClause[1];
  406. return $sql;
  407. } else {
  408. return false;
  409. }
  410. }
  411. function adodb_key_exists($key, &$arr,$force=2)
  412. {
  413. if ($force<=0) {
  414. // the following is the old behaviour where null or empty fields are ignored
  415. return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
  416. }
  417. if (isset($arr[$key])) return true;
  418. ## null check below
  419. if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
  420. return false;
  421. }
  422. /**
  423. * There is a special case of this function for the oci8 driver.
  424. * The proper way to handle an insert w/ a blob in oracle requires
  425. * a returning clause with bind variables and a descriptor blob.
  426. *
  427. *
  428. */
  429. function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
  430. {
  431. static $cacheRS = false;
  432. static $cacheSig = 0;
  433. static $cacheCols;
  434. $tableName = '';
  435. $values = '';
  436. $fields = '';
  437. $recordSet = null;
  438. $arrFields = _array_change_key_case($arrFields);
  439. $fieldInsertedCount = 0;
  440. if (is_string($rs)) {
  441. //ok we have a table name
  442. //try and get the column info ourself.
  443. $tableName = $rs;
  444. //we need an object for the recordSet
  445. //because we have to call MetaType.
  446. //php can't do a $rsclass::MetaType()
  447. $rsclass = $zthis->rsPrefix.$zthis->databaseType;
  448. $recordSet =& new $rsclass(-1,$zthis->fetchMode);
  449. $recordSet->connection = &$zthis;
  450. if (is_string($cacheRS) && $cacheRS == $rs) {
  451. $columns =& $cacheCols;
  452. } else {
  453. $columns = $zthis->MetaColumns( $tableName );
  454. $cacheRS = $tableName;
  455. $cacheCols = $columns;
  456. }
  457. } else if (is_subclass_of($rs, 'adorecordset')) {
  458. if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
  459. $columns =& $cacheCols;
  460. } else {
  461. for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
  462. $columns[] = $rs->FetchField($i);
  463. $cacheRS = $cacheSig;
  464. $cacheCols = $columns;
  465. $rs->insertSig = $cacheSig++;
  466. }
  467. $recordSet =& $rs;
  468. } else {
  469. printf(ADODB_BAD_RS,'GetInsertSQL');
  470. return false;
  471. }
  472. // Loop through all of the fields in the recordset
  473. foreach( $columns as $field ) {
  474. $upperfname = strtoupper($field->name);
  475. if (adodb_key_exists($upperfname,$arrFields,$force)) {
  476. $bad = false;
  477. if (strpos($upperfname,' ') !== false)
  478. $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
  479. else
  480. $fnameq = $upperfname;
  481. $type = $recordSet->MetaType($field->type);
  482. /********************************************************/
  483. if (is_null($arrFields[$upperfname])
  484. || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
  485. || $arrFields[$upperfname] === 'null'
  486. )
  487. {
  488. switch ($force) {
  489. case 0: // we must always set null if missing
  490. $bad = true;
  491. break;
  492. case 1:
  493. $values .= "null, ";
  494. break;
  495. case 2:
  496. //Set empty
  497. $arrFields[$upperfname] = "";
  498. $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
  499. break;
  500. default:
  501. case 3:
  502. //Set the value that was given in array, so you can give both null and empty values
  503. if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') {
  504. $values .= "null, ";
  505. } else {
  506. $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
  507. }
  508. break;
  509. } // switch
  510. /*********************************************************/
  511. } else {
  512. //we do this so each driver can customize the sql for
  513. //DB specific column types.
  514. //Oracle needs BLOB types to be handled with a returning clause
  515. //postgres has special needs as well
  516. $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
  517. $arrFields, $magicq);
  518. }
  519. if ($bad) continue;
  520. // Set the counter for the number of fields that will be inserted.
  521. $fieldInsertedCount++;
  522. // Get the name of the fields to insert
  523. $fields .= $fnameq . ", ";
  524. }
  525. }
  526. // If there were any inserted fields then build the rest of the insert query.
  527. if ($fieldInsertedCount <= 0) return false;
  528. // Get the table name from the existing query.
  529. if (!$tableName) {
  530. if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
  531. $tableName = $tableName[1];
  532. else
  533. return false;
  534. }
  535. // Strip off the comma and space on the end of both the fields
  536. // and their values.
  537. $fields = substr($fields, 0, -2);
  538. $values = substr($values, 0, -2);
  539. // Append the fields and their values to the insert query.
  540. return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
  541. }
  542. /**
  543. * This private method is used to help construct
  544. * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
  545. * It handles the string construction of 1 column -> sql string based on
  546. * the column type. We want to do 'safe' handling of BLOBs
  547. *
  548. * @param string the type of sql we are trying to create
  549. * 'I' or 'U'.
  550. * @param string column data type from the db::MetaType() method
  551. * @param string the column name
  552. * @param array the column value
  553. *
  554. * @return string
  555. *
  556. */
  557. function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
  558. {
  559. $sql = '';
  560. // Based on the datatype of the field
  561. // Format the value properly for the database
  562. switch($type) {
  563. case 'B':
  564. //in order to handle Blobs correctly, we need
  565. //to do some magic for Oracle
  566. //we need to create a new descriptor to handle
  567. //this properly
  568. if (!empty($zthis->hasReturningInto)) {
  569. if ($action == 'I') {
  570. $sql = 'empty_blob(), ';
  571. } else {
  572. $sql = $fnameq. '=empty_blob(), ';
  573. }
  574. //add the variable to the returning clause array
  575. //so the user can build this later in
  576. //case they want to add more to it
  577. $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
  578. } else if (empty($arrFields[$fname])){
  579. if ($action == 'I') {
  580. $sql = 'empty_blob(), ';
  581. } else {
  582. $sql = $fnameq. '=empty_blob(), ';
  583. }
  584. } else {
  585. //this is to maintain compatibility
  586. //with older adodb versions.
  587. $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
  588. }
  589. break;
  590. case "X":
  591. //we need to do some more magic here for long variables
  592. //to handle these correctly in oracle.
  593. //create a safe bind var name
  594. //to avoid conflicts w/ dupes.
  595. if (!empty($zthis->hasReturningInto)) {
  596. if ($action == 'I') {
  597. $sql = ':xx'.$fname.'xx, ';
  598. } else {
  599. $sql = $fnameq.'=:xx'.$fname.'xx, ';
  600. }
  601. //add the variable to the returning clause array
  602. //so the user can build this later in
  603. //case they want to add more to it
  604. $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
  605. } else {
  606. //this is to maintain compatibility
  607. //with older adodb versions.
  608. $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
  609. }
  610. break;
  611. default:
  612. $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
  613. break;
  614. }
  615. return $sql;
  616. }
  617. function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
  618. {
  619. if ($recurse) {
  620. switch($zthis->dataProvider) {
  621. case 'postgres':
  622. if ($type == 'L') $type = 'C';
  623. break;
  624. case 'oci8':
  625. return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
  626. }
  627. }
  628. $sql = '';
  629. switch($type) {
  630. case "C":
  631. case "X":
  632. case 'B':
  633. if ($action == 'I') {
  634. $sql = $zthis->qstr($arrFields[$fname],$magicq) . ", ";
  635. } else {
  636. $sql .= $fnameq . "=" . $zthis->qstr($arrFields[$fname],$magicq) . ", ";
  637. }
  638. break;
  639. case "D":
  640. if ($action == 'I') {
  641. $sql = $zthis->DBDate($arrFields[$fname]) . ", ";
  642. } else {
  643. $sql .= $fnameq . "=" . $zthis->DBDate($arrFields[$fname]) . ", ";
  644. }
  645. break;
  646. case "T":
  647. if ($action == 'I') {
  648. $sql = $zthis->DBTimeStamp($arrFields[$fname]) . ", ";
  649. } else {
  650. $sql .= $fnameq . "=" . $zthis->DBTimeStamp($arrFields[$fname]) . ", ";
  651. }
  652. break;
  653. default:
  654. $val = $arrFields[$fname];
  655. if (empty($val)) $val = '0';
  656. if ($action == 'I') {
  657. $sql .= $val . ", ";
  658. } else {
  659. $sql .= $fnameq . "=" . $val . ", ";
  660. }
  661. break;
  662. }
  663. return $sql;
  664. }
  665. function _adodb_debug_execute(&$zthis, $sql, $inputarr)
  666. {
  667. global $HTTP_SERVER_VARS;
  668. $ss = '';
  669. if ($inputarr) {
  670. foreach($inputarr as $kk=>$vv) {
  671. if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
  672. $ss .= "($kk=>'$vv') ";
  673. }
  674. $ss = "[ $ss ]";
  675. }
  676. $sqlTxt = str_replace(',',', ',is_array($sql) ? $sql[0] : $sql);
  677. // check if running from browser or command-line
  678. $inBrowser = isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']);
  679. $dbt = $zthis->databaseType;
  680. if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
  681. if ($inBrowser) {
  682. $ss = htmlspecialchars($ss);
  683. if ($zthis->debug === -1)
  684. ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<br>\n",false);
  685. else
  686. ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr>\n",false);
  687. } else {
  688. ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
  689. }
  690. $qID = $zthis->_query($sql,$inputarr);
  691. /*
  692. Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
  693. because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
  694. */
  695. if ($zthis->databaseType == 'mssql') {
  696. // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
  697. if($emsg = $zthis->ErrorMsg()) {
  698. if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
  699. }
  700. } else if (!$qID) {
  701. ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
  702. }
  703. return $qID;
  704. }
  705. function _adodb_backtrace($printOrArr=true,$levels=9999)
  706. {
  707. if (PHPVERSION() < 4.3) return '';
  708. $html = (isset($_SERVER['HTTP_USER_AGENT']));
  709. $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
  710. $MAXSTRLEN = 128;
  711. $s = ($html) ? '<pre align=left>' : '';
  712. if (is_array($printOrArr)) $traceArr = $printOrArr;
  713. else $traceArr = debug_backtrace();
  714. array_shift($traceArr);
  715. array_shift($traceArr);
  716. $tabs = sizeof($traceArr)-2;
  717. foreach ($traceArr as $arr) {
  718. $levels -= 1;
  719. if ($levels < 0) break;
  720. $args = array();
  721. for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
  722. $tabs -= 1;
  723. if ($html) $s .= '<font face="Courier New,Courier">';
  724. if (isset($arr['class'])) $s .= $arr['class'].'.';
  725. if (isset($arr['args']))
  726. foreach($arr['args'] as $v) {
  727. if (is_null($v)) $args[] = 'null';
  728. else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
  729. else if (is_object($v)) $args[] = 'Object:'.get_class($v);
  730. else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
  731. else {
  732. $v = (string) @$v;
  733. $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
  734. if (strlen($v) > $MAXSTRLEN) $str .= '...';
  735. $args[] = $str;
  736. }
  737. }
  738. $s .= $arr['function'].'('.implode(', ',$args).')';
  739. $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
  740. $s .= "\n";
  741. }
  742. if ($html) $s .= '</pre>';
  743. if ($printOrArr) print $s;
  744. return $s;
  745. }
  746. ?>